下面的代码正确地检查类型 T
是否有方法 sort
。但是,当我通过将 decltype(&U::sort,...)
更改为 decltype(U::sort,.. .)
(符号 &
被移除),则代码始终返回 false
。
为什么?
为什么名字本身就不够用? &
是什么意思?
#include <iostream>
#include <type_traits>
template <typename T>
class has_sort {
template <typename U>
static auto check(bool) -> decltype(&U::sort, std::true_type()); // (*)
template <typename U>
static std::false_type check(...);
public:
using type = decltype(check<T>(true));
static bool const value = type::value;
};
int main() {
struct Foo { void sort(); };
struct Foo2 { void sort2(); };
std::cout << "Foo: " << has_sort<Foo>::value << std::endl;
std::cout << "Foo2: " << has_sort<Foo2>::value << std::endl;
std::cout << "int: " << has_sort<int>::value << std::endl;
}
最佳答案
答案很简单:没有&
就不能获取成员函数的地址。你不能自己尝试:
auto fun = Foo::sort; // error
标准要求成员函数指针必须与&
一起使用,因为没有它语法会产生歧义。想象一下,在模板中:
template<typename T>
void test() {
T::test2; // is it a member function pointer or static data member?
}
所以 sfinae 检查是正确的:没有 &
,如果类型 T
有一个名为 sort的静态数据成员,检查将为真
.
然而,你可以用这个技巧绕过这个限制,尽管它是为了演示目的,我不建议你这样做:
struct Foo {
void sortImpl();
static constexpr auto sort = &Foo::sortImpl;
};
然后检查名为 sort
的静态数据成员是正确的,sort
将是一个函数指针。
关于c++ - SFINAE 在函数前加符号与其名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39811436/