【问题标题】:How to delete copy/move instantiation of variadic template constructor如何删除可变参数模板构造函数的复制/移动实例化
【发布时间】:2017-12-07 22:48:00
【问题描述】:

假设这是我的班级:

#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'
}

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

【问题讨论】:

  • See this thread - 您可以使用 SFINAE 或虚拟参数从转发构造函数中“删除”复制构造案例

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


【解决方案1】:

您可以使用SFINAEstd::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

【讨论】:

  • 您添加了MyClass() = default;,它不会初始化成员v,而可变参数模板构造函数零初始化它。
猜你喜欢
  • 2016-09-02
  • 1970-01-01
  • 2011-05-24
  • 2016-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多