C++ 如何删除可变模板构造函数的复制/移动实例化

C++ 如何删除可变模板构造函数的复制/移动实例化,c++,c++11,templates,template-meta-programming,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(MyClas

假设这是我的班级:

#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'
}
#包括
#包括
模板
类MyClass{
电视
公众:
模板
MyClass(Ts&…args):v{std::forward(args)…}{
MyClass(MyClass常量&)=默认值;
MyClass(MyClass&&)=默认值;
};
另一类{
公众:
运算符MyClass(){
返回{};
}
};
int main(){
MyClass mc;
MyClass mc2{mc};//错误:无法从“MyClass”转换为“int”
其他类别oc;
MyClass mc3{oc};//错误:无法从“OtherClass”转换为“int”
}
如何正确防止可变模板构造函数实例化复制/移动构造函数?

您可以应用来限制类型,例如

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;
};
模板
结构getFirstType{
使用类型=无效;
};
模板
结构getFirstType{
使用类型=T;
};
模板
类MyClass{
电视
公众:
//仅当参数包的第一种类型不是MyClass时有效
模板>
MyClass(Ts&…args):v{std::forward(args)…}{
MyClass(MyClass常量&)=默认值;
MyClass(MyClass&&)=默认值;
};

-您可以使用SFINAE或伪参数从转发构造中“删除”复制构造案例,您已经添加了
MyClass()=default
不初始化成员
v
,而可变模板构造函数zero初始化它。