c++ - 为什么类模板的成员函数声明都应该是良构的?

标签 c++ templates sfinae

好的,假设我想检查模板参数是否有嵌套类型/typedef XYZ。

template <class T>
struct hasXZY
{
   typedef char                  no;
   typedef struct { char x[2]; } yes;
   template <class U>
   static yes f(typename U::XYZ*);
   template <class /*U*/>
   static no  f(...);
   enum {value = sizeof(f<T>(0))==sizeof(yes)};
};

工作正常,符合预期。

现在考虑一下:

template <class T>
struct hasXZY
{
   typedef char                  no;
   typedef struct { char x[2]; } yes;

   static yes f(typename T::XYZ*);
   static no  f(...);
   enum {value = sizeof(f(0))==sizeof(yes)};
};

hasXYZ<int>现在会导致编译时错误。好的,f 不是模板函数。但另一方面,当hasXYZ通过 hasXYZ<int>::value 为 int 实例化, 编译器可以很容易地排除 f(int::XYZ*)从候选人名单。我只是不明白为什么类模板中成员函数声明的实例化失败一定会导致整个类实例化失败。有什么想法吗?

编辑: 我的问题是:为什么成员函数声明应该全部格式正确?由于编译器仅在使用时实例化这些方法,为什么它需要正确的声明。将上面的示例 2 视为此功能的可能用例。

最佳答案

SFINAE 仅在为函数重载决策创建候选集时使用。在您的第一个示例中,您正在调用重载的 f() 函数,由于 SFINAE,第一个被排除在外。

在你的第二个例子中,当实例化 hasXZY 时,它的所有成员都必须定义良好,并且模板参数的替换不能失败。它适用于 int::XYZ。

成员不会因为替换失败而被排除在类(class)之外。

关于c++ - 为什么类模板的成员函数声明都应该是良构的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4000288/

相关文章:

c++ - 在库中使用模板

c++ - 将 std::invoke_result_t 与通用 lambda 一起使用时出现硬错误

c++ - 按位与等于 0 的整数对

c++ - 在 C++ 的 vector resize() 函数中随机化构造函数参数

c++ - 模板参数推导/替换失败,lambda 作为函数指针

c++ - 如何实现 is_enum_class 类型特征?

c++ - 模板成员函数上的外线 sfinae 是否可能?

c++ - 传递 mat 引用时出现 opencv malloc 错误

c++ - 可移植写入器-读取器自旋锁

c++ - 不匹配 operator= 错误