如何使用std::enable_if根据模板参数控制类成员函数的可见性
问题原因
你原来的写法会编译失败是因为SFINAE规则仅适用于函数模板自身的模板参数推导过程,你现在std::enable_if的判断条件直接依赖类模板的参数T,当类实例化时(比如myClass<float>),会直接计算这个条件,条件为false时std::enable_if没有type成员,直接触发编译错误,不会触发SFINAE的“替换失败非错误”逻辑。
正确实现方式
只需要给成员函数模板加一个默认模板参数,让enable_if的判断条件依赖该函数自身的模板参数即可:
#include <type_traits> #include <string> template < typename T > class myClass { public: using value_type = T; using other_type = int; myClass() = default; virtual ~myClass() = default; // 基础版本,所有场景都可用 void function(const value_type& val) {}; // 重载版本,仅当other_type不可隐式转换为value_type时生效 template <typename U = value_type, typename = std::enable_if_t<!std::is_convertible_v<other_type, U>>> void function(const other_type& val) {}; }; int main(int argc, char const *argv[]) { myClass< std::string > foo; // OK,int不能转string,两个function重载都存在 myClass< float > bar; // OK,int可以转float,仅保留基础版本function return 0; }
如果是C11环境,把C14开始支持的别名模板替换为全称即可:
template <typename U = value_type, typename = typename std::enable_if<!std::is_convertible<other_type, U>::value>::type> void function(const other_type& val) {};
内容的提问来源于stack exchange,提问作者joaocandre
相关产品推荐
相关产品推荐

