如何删除variadic模板构造函数的复制/移动实例化

时间:2017-12-07 02:09:07

标签: c++ c++11 templates template-meta-programming

假设这是我的班级:

#include<utility>
#include<type_traits>

template<typename T>
class MyClass {
    T v;
public:
    template<typename...Ts>
    MyClass(Ts&&...args) :v{ std::forward<Ts>(args)... } {}

    MyClass(MyClass const&) = default;
    MyClass(MyClass &&) = default;
};

class OtherClass {
public:
    operator MyClass<int>() {
        return{};
    }
};

int main(){
    MyClass<int> mc;
    MyClass<int> mc2{ mc }; // error: cannot convert from 'MyClass<int>' to 'int'
    OtherClass oc;
    MyClass<int> mc3 {oc};  // error: cannot convert from 'OtherClass' to 'int'
}

如何正确阻止可变参数模板构造函数实例化复制/移动构造函数?

1 个答案:

答案 0 :(得分:1)

您可以使用SFINAE std::enable_if来限制类型,例如

template <typename... Ts>
struct getFirstType {
    using type = void;
};
template <typename T, typename... Ts>
struct getFirstType<T, Ts...> {
    using type = T;
};

template<typename T>
class MyClass {
    T v;
public:
    // only valid when the first type of parameter pack is NOT MyClass
    template<typename...Ts, 
             typename = std::enable_if_t<
                 !std::is_same_v<MyClass, 
                                 std::decay_t<typename getFirstType<Ts...>::type>>>>
    MyClass(Ts&&...args) :v{ std::forward<Ts>(args)... } {}

    MyClass(MyClass const&) = default;
    MyClass(MyClass &&) = default;
};

LIVE