编辑,为了避免混淆:
decltype不不接受两个参数.看到答案.
以下两个结构可用于T在编译期间检查类型上成员函数的存在性:
// Non-templated helper struct:
struct _test_has_foo {
template<class T>
static auto test(T* p) -> decltype(p->foo(), std::true_type());
template<class>
static auto test(...) -> std::false_type;
};
// Templated actual struct:
template<class T>
struct has_foo : decltype(_test_has_foo::test<T>(0))
{};
Run Code Online (Sandbox Code Playgroud)
我认为这个想法是在检查成员函数的存在时使用SFINAE,因此如果p->foo()无效,则只test返回返回的省略号版本std::false_type.否则,第一个方法被定义T*并将返回std::true_type.实际的"切换"发生在第二个类中,它继承自返回的类型test.与不同的方法相比,这看起来更聪明,更"轻巧" is_same.
在decltype与两个参数第一次看令我感到诧异,因为我认为这只是得到一个表达式的类型.当我看到上面的代码时,我认为它类似于"尝试编译表达式并始终返回第二种类型.如果表达式无法编译则失败"(所以隐藏此专业化; SFINAE).
但:
然后我想我可以使用这个方法来编写任何"is valid expression"检查器,只要它依赖于某种类型T.例:
...
template<class T>
static auto test(T* p) -> decltype(bar(*p), std::true_type());
...
Run Code Online (Sandbox Code Playgroud)
这一点,所以我想,将返回 …