【问题标题】:how to distinguish function type with SFINAE如何用 SFINAE 区分函数类型
【发布时间】:2018-06-10 16:08:16
【问题描述】:

我正在看书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] 一起工作。我以前从未见过这种情况。

【问题讨论】:

  • 你不能有函数数组,这是会发生替换失败的地方。
  • 我认为这个模板不能按预期工作。例如,引用也不能归类为数组,因此该模板会将引用类型视为函数类型。

标签: c++ sfinae


【解决方案1】:

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

sizeof 是测试函数的返回类型,测试函数的实际结果没有被使用,因为 test() 从来没有真正被调用过,只测试它的返回类型。

【讨论】:

  • 我相信问题在于它为什么起作用,而不仅仅是指针。
【解决方案2】:

简而言之,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 中提取的。

【讨论】:

  • 右值引用仍未涵盖。 volatile voidconst volatile void 也不是。
  • 联系本书的作者,而不是我。
猜你喜欢
  • 1970-01-01
  • 2017-01-14
  • 1970-01-01
  • 1970-01-01
  • 2010-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多