如何区分功能类型与SFINAE

时间:2017-12-30 16:31:39

标签: c++ sfinae

我正在阅读本书 C ++模板。它提到SFINAE(替换失败不是错误)主体可用于检测函数类型。 代码示例:

template <typename T>
class IsFunctionT {
private:
   typedef char One;
   typedef struct { char a[2]; } Two;
   template<typename U> static One test(...);
   template<typename U> static Two test(U (*)[1]); // This test overloading I cannot understand 
public:
   enum { Yes = sizeof(IsFunctionT<T>::test<T>(0) == 1};
   enum { No = !Yes };
};

我理解它的目的是找到不能归类为数组的函数,但它如何与U (*)[1]一起使用。我以前从未见过这个。

2 个答案:

答案 0 :(得分:0)

U()[1]是一个指向1个元素数组的未命名指针。并且0被视为一个int或一个指向U()[1]的空指针;

sizeof正在测试函数返回类型,测试函数的实际结果未被使用,因为test()实际上从未被调用,只测试了它的返回类型。

答案 1 :(得分:0)

简而言之,SFINAE通过替换一种类型来工作,如果表达形式不正确则不会造成严重失败。例如,您不能拥有一个函数数组,因此如果U是一个函数,则替换将失败并且将丢弃该重载。现在正如评论所指出的那样,您单独发布的代码并未涵盖所有案例。您需要其他专业化,即:

template<typename T>
class IsFunctionT<T&> {
  public:
    enum { Yes = 0 };
    enum { No = !Yes };
};

template<>
class IsFunctionT<void> {
  public:
    enum { Yes = 0 };
    enum { No = !Yes };
};

template<>
class IsFunctionT<void const> {
  public:
    enum { Yes = 0 };
    enum { No = !Yes };
};

我从免费提供的source code from the book中提取。