繁体   English   中英

在成员容器中使用仅移动但可克隆类型的复制构造函数

[英]Copy constructors with move-only, but cloneable types in member containers

假设我们有两种类型, T1T2

除了以下事实外, T1并不重要:

  • 它不是可复制构造的
  • 它有一个移动构造函数
  • 我们有一个很好的函数,带有签名T1 copy(T1 const& orig) ,它创建了一个副本。

T2可以简化为以下类:

// T2.h
class T2 {
public:
    T2() { /* initializes the vector with something */ }
    T2(T2 const& other);
private:
    std::vector<T1> v;
}

// T2.cpp

T2::T2(T2 const& other) : ... {}

如果您只能写入省略号部分或全局范围,您将如何实现此方法?

一个简单的现实世界用例 - 假设“你不能在大括号之间写任何东西”部分是现实世界的限制:

  • T1std::unique_ptr<anything>
  • copystd::make_unique
  • anything都有一个复制构造函数

我对实现还有两个额外的要求:

  • 表现。 它不应该(相当)比在复制构造函数体中使用for循环的幼稚实现慢。
  • 可读性。 问题背后的重点是做一些比简单的 for 循环更清晰/干净的事情(例如,想象 T2 具有两个或更多成员向量)。

和可选的,但很高兴有功能:

  • 很容易推广到其他容器的东西
  • 只适用于迭代器的东西
  • 通用的东西

澄清:我知道这个问题可以用std::vector<T1> copy_vec(std::vector<T1> const& orig)全局函数std::vector<T1> copy_vec(std::vector<T1> const& orig) 将该函数放入T2.cpp的匿名命名空间也会使其成为本地,但我会反对它的可读性,我认为它根本不会比 for 循环更好。 如果复制构造函数不在实现文件中而是内联在标题中,这显然是一个糟糕的解决方案。

所以我的问题的改写是:

  • 是否已经实现了类似的东西,我可以包括在内?
  • 如果没有,那为什么呢? 我并不是说我考虑了每一个角落情况,但我认为这可能可以以一种很好的通用方式实现,并且由于unique_ptr ,这是一个足够常见的情况。

天真的循环没有错:

v.reserve(other.v.size());
for (auto& elem : other.v) {
    v.push_back(copy(elem));
}

这是足够的可读性和最佳。

虽然我猜现代的、聪明的解决方案是使用range-v3

T2(T2 const& other)
: v(other.v | view::transform(copy))
{ } 

我不确定这是否比循环更好以证明额外的复杂性,但 YMMV。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM