元函数接受要在模板中检查的类型。如果在 Method<given_type> 上定义了括号运算符,则元函数必须返回 true。否则为假。
#include <iostream>
#include <functional>
template<typename T>
struct Method {};
template<>
struct Method<int> {
int operator()() { return 1; }
};
template<class T>
struct is_brackets_op_defined {
static void Check(...);
template<typename C>
static decltype(Method<C>::operator()) Check(const C&);
using type = decltype(Check(
std::declval< Method<T> >()
));
constexpr static bool value =
!std::is_same<void, type>();
};
int main() {
std::cout << is_brackets_op_defined<float>::value << std::endl;
}
即使存在特化,我的实现也总是返回 false(此处为 int)
std::cout << is_brackets_op_defined<float>::value // false
std::cout << is_brackets_op_defined<int >::value // false
调试元程序并不是最简单的事情,但无论如何我们都会尝试。
is_brackets_op_defined<float>首先,让我们删除static void Check(...);. 这将帮助我们了解为什么编译器不喜欢重载版本Check(代码)。好吧,作为一个
C功能Check来了Method<int>。显然,在这种情况下,构造对和Method<C>::operator()都给出了编译错误。根据 SFINAE,编译器会丢弃这个重载。intfloat我们需要以某种方式更改此表达式,以便它扩展为某种类型 for
int并给出替换失败的 forfloat。在我看来&C::operator(),这将是正确的(代码)。原则上,这可以停止,但我不能不建议稍微简化代码。您可以将其用作返回值
std::true_type,std::false_type这将丢弃std::is_same.UPD。评论中的问题提出了第二个改进。
const C&您可以改用const C*. 这将摆脱std::declval,由于某种原因,它会在 GCC 下生成类型不完整的编译错误。我不知道为什么您的代码不起作用,但是有一些东西可以使它起作用:
您的代码中有一个明显的问题:
Method<C>::operator()不正确的 C++,因为 它是一个不做任何事情的成员函数。你需要打电话给她或获取她的地址。它可以是这样的。请注意,辅助函数也是一个模板:
在线编译器