如何声明SFINAE类?浮点数模板类外部定义方法编译失败求助
关于仅接受浮点数模板参数的类声明及外部方法定义问题
嘿,我来帮你捋清楚这个问题~首先先纠正一个可能的笔误:你写的swift::enable_if应该是std::enable_if吧?记得要包含<type_traits>头文件才能使用这个模板哦。
先回答第一个问题:你这个类的声明方式是可行的,通过模板默认参数结合std::enable_if做SFINAE,确实能限制模板参数T只能是浮点数类型。但你没法在类外部定义方法的核心原因是:外部定义成员函数时,必须完整复制类的模板参数列表(包括那个enable_if的默认参数部分),否则编译器没法把成员函数和你的类模板关联起来。
举个完整的例子帮你理解:
第一步:类的声明(头文件中)
#include <type_traits> #include <iostream> template <typename T, std::enable_if<std::is_floating_point<T>::value, void*> = nullptr> class my_float { public: // 声明成员函数 void print() const; T add(T other) const; private: T value = 0.0; };
第二步:类外部的成员函数定义
// 必须完整写出模板参数列表,和类声明完全一致 template <typename T, std::enable_if<std::is_floating_point<T>::value, void*> = nullptr> void my_float<T>::print() const { std::cout << "Value: " << value << std::endl; } template <typename T, std::enable_if<std::is_floating_point<T>::value, void*> = nullptr> T my_float<T>::add(T other) const { return value + other; } // 如果需要把类编译进静态库/动态库,别忘了显式实例化需要的类型 template class my_float<float>; template class my_float<double>; template class my_float<long double>;
为什么必须这么写?
因为你的类模板的参数列表包含了第二个enable_if参数(哪怕它有默认值),成员函数作为类模板的一部分,其模板参数必须和类的模板参数完全匹配。如果省略了第二个参数,编译器会认为你在定义一个全新的、参数列表不同的模板函数,自然找不到对应的类成员,就会报编译错误。
另外,如果你觉得每次写这么长的模板参数麻烦,可以用C++14引入的std::enable_if_t来简化写法,比如把模板参数写成:
template <typename T, std::enable_if_t<std::is_floating_point<T>::value, void*> = nullptr>
效果和原来的写法完全一样,但代码更简洁。
内容的提问来源于stack exchange,提问作者user3600124
相关产品推荐
相关产品推荐

