c++ - 构造函数重载和 SFINAE

标签 c++ c++14 enable-if

作为理解 std::enable_if 用法的练习,我尝试实现一个包装类(结构)来表示任何给定时间点的特定类型:

#include<type_traits>
#include<typeinfo>
#include<iostream>
using std::enable_if;
using std::is_same;
using std::cout;
using std::endl;

template<typename T>
struct type_wrap{

                 type_wrap(typename enable_if<is_same<int,T>::value,T>::type&& rrT):value(rrT){
                         cout << "The wrapped type is " << typeid(value).name() << endl;
                         cout << "The wrapped value is " << value << endl;
                } 
                 type_wrap(typename enable_if<is_same<float,T>::value,T>::type && rrT):value(rrT){
                         cout << "The wrapped type is " << typeid(value).name() << endl;
                         cout << "The wrapped value is " << value << endl;
                 }

                 T& value;
};

int main(){

        type_wrap<int>(0);
        type_wrap<float>(0.5);
        return(0);
}

上面的代码无法编译:

so_main.cpp:16:47: error: no type named 'type' in 'std::__1::enable_if<false, int>'; 'enable_if' cannot be used to disable this declaration
                 type_wrap(typename enable_if<is_same<float,T>::value,T>::type && rrT):value(rrT){
                                              ^~~~~~~~~~~~~~~~~~~~~~~
so_main.cpp:26:9: note: in instantiation of template class 'type_wrap<int>' requested here
        type_wrap<int>(0);
        ^
so_main.cpp:12:47: error: no type named 'type' in 'std::__1::enable_if<false, float>'; 'enable_if' cannot be used to disable this declaration
                 type_wrap(typename enable_if<is_same<int,T>::value,T>::type&& rrT):value(rrT){
                                              ^~~~~~~~~~~~~~~~~~~~~
so_main.cpp:27:9: note: in instantiation of template class 'type_wrap<float>' requested here
        type_wrap<float>(0.5);
        ^
2 errors generated.

如果我要从 main() 中删除其中一个重载的构造函数以及相应的实例化,该代码就会起作用。但这违背了本次练习的全部目的。

谁能指出编译错误的原因吗?

最佳答案

SFINAE 适用于模板方法(/构造函数),这里是您的类模板,您可以使用以下内容(即使特化在您的情况下看起来更简单/更好):

template<typename T>
struct type_wrap{
    template <typename U,
              std::enable_if_t<std::is_same<int, U>::value
                               && is_same<int, T>::value>* = nullptr>
    type_wrap(U arg) : value(arg){
        // Int case
        std::cout << "The wrapped type is " << typeid(value).name() << std::endl;
        std::cout << "The wrapped value is " << value << std::endl;
    }

    template <typename U,
              std::enable_if_t<std::is_same<float, U>::value
                               && is_same<float, T>::value>* = nullptr>
    type_wrap(U arg) : value(arg){
        // float case
        std::cout << "The wrapped type is " << typeid(value).name() << std::endl;
        std::cout << "The wrapped value is " << value << std::endl;
    }
    T value;
};

Demo

关于c++ - 构造函数重载和 SFINAE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49548082/

相关文章:

c++ - 非模板化成员函数的 enable_if 用法

c++ - Boost enable_if问题

c++ - 表达式 std::enable_if 中的 type* 是什么

c++ - 插入字符串 C++

c++ - Gsoap 文件已留在@

c++ - 有没有办法检查 std::function 是否指向有效对象的成员?

C++ 强制函数参数求值顺序

c++ - 如何在 C++ 中处理灵活的数组

c++ - std::map 中的下一个值

c++ - 执行 constexpr 运算符重载的指南?