【问题标题】:Disable Copy constructor of template class禁用模板类的复制构造函数
【发布时间】:2020-07-27 21:33:17
【问题描述】:

如何禁用模板类的复制构造函数。

例如:

template<typename T>
struct X {
    T property;
    constexpr X(const T property): property(property) { }

    friend std::ostream& operator<<(std::ostream& out, const X& x) {
        return out << "{ " << x.property << " }";
    }
};

问题:

如果我让类包含它自己

constexpr X x1 { 1 };
std::cout << x1 << "\n"; // prints "{ 1 }"
constexpr X x2 { x1 };
std::cout << x2 << "\n"; // prints "{ 1 }", expected "{ { 1 } }"

我的假设是调用了复制构造函数。 删除复制构造函数没有帮助。然后我得到一个编译时错误。

【问题讨论】:

  • Deleting the copy constructor does not help.你是怎么做到的?
  • 某事模板参数推断。修复它,复制构造函数甚至不会成为构造 x2 的候选对象。
  • 我删除了constexpr X(const X&amp;) = delete;的拷贝构造函数。
  • 请注意,您想要删除或禁用复制构造函数,因为X&lt;X&lt;int&gt;&gt; 实例化中的 ctor-initializer 列表将需要它。
  • 您的示例无法编译。它在修复 ideone.com/sLdeKH 后工作

标签: c++ templates constructor


【解决方案1】:

您可以使用模板辅助函数

template<typename T>
X<T> helper(const T& x) {
    return x;  // This will invoke the construtor
}

那么当使用时

helper(x1);

类型T 将被正确发现为X&lt;int&gt;

【讨论】:

  • 我认为这样做有点丑陋,但它确实有效!谢谢。我想这也是 make_unique 等的原因?
  • @ArwedMett:嗯,make_unique 和类似的函数是在 C++ 版本中制作的,这些版本在变量声明中根本没有类模板参数推导。对于 C++17 及更高版本,您需要推导指南而不是工厂函数。
【解决方案2】:

好的,感谢 Ben Voigt,我为 C++17 找到了更好的解决方案。

template<typename T>
struct X {
    T property;
    constexpr X(const T property): property(property) { }

    friend std::ostream& operator<<(std::ostream& out, const X& x) {
        return out << "{ " << x.property << " }";
    }
};

你需要添加一个扣除指南:

template<typename T>
X(X<T>) -> X<X<T>>;

【讨论】:

    猜你喜欢
    • 2016-03-22
    • 1970-01-01
    • 1970-01-01
    • 2015-12-08
    • 2018-04-01
    • 1970-01-01
    • 2011-05-24
    • 1970-01-01
    相关资源
    最近更新 更多