c++ - SFINAE 在函数前加符号与其名称

标签 c++ templates c++11

下面的代码正确地检查类型 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/

相关文章:

c++ - 在模板化类型中用其他类型递归替换类型

c++ - strcpy_s 不适用于 gcc

c++ - 继承虚基类的构造函数

c++ - 为平台上可用的所有整数定义一个函数

c++ - 在不使用 modf() 的情况下获取 float 的小数部分

c++ - 如何使继承的虚函数不可用?

c++ - 从文件中删除一个以 & 开头然后有 23 个字符的字符串

C++ 中的 PHP 样式 foreach 循环

C++ 删除指针

c++ - 为什么 clang 和 gcc 在这个虚拟继承代码上意见不一?