我可以在向量中使用`unique_ptr`,还是需要切换到`shared_ptr`?

时间:2014-09-10 15:51:33

标签: c++ std

鉴于此类具有unique_ptr:

class MyClass
{
public:
  MyClass(){}
  MyClass(MyClass &&other) : ptr(std::move(other.ptr)){}

  std::unique_ptr <int> ptr;
};

有没有办法让std::vector<MyClass>成为可能?

void ThisBreaksIt()
{
  MyClass instance;
  std::vector<MyClass> mv;
  mv.push_back(instance);
}

按原样,这给了我错误

error C2248: 'std::unique_ptr<_Ty>::unique_ptr' : cannot access private member declared in class 'std::unique_ptr<_Ty>'

这是有道理的,因为我没有复制构造函数,并且当编译器尝试创建默认复制构造函数时,它会尝试复制unique_ptr,这是不允许的。

我可以通过添加这个构造函数来编译它:

  MyClass(const MyClass&){}

但是,当然,这会使unique_ptr未初始化,而不是我想要的。

我无法添加

  MyClass(const MyClass& other) : ptr(std::move(other.ptr)){}

因为它是const,我无法在const对象上调用std :: move()。我可以创建构造函数

  MyClass(MyClass& other) : ptr(std::move(other.ptr)){}

但是没有解决原始的编译错误,因为vector::push_back使用const复制构造函数。

所以,我被卡住了。有没有办法做我想做的事情?

如果我只使用shared_ptr代替unique_ptr,所有这些问题都会消失。那是我应该做的吗?

2 个答案:

答案 0 :(得分:6)

在向量中存储不可复制的类型没有问题;它只需要移动,就像你的那样。

问题在于:

mv.push_back(instance);

尝试插入instance的副本,并且该类不可复制。但它是可移动的:

mv.push_back(std::move(instance));

请注意,在此示例中,无需编写自己的默认值和移动构造函数。隐含的将完全按照你的要求行事。

答案 1 :(得分:0)

您可以使用emplace_back。这只允许添加rvalues。

因此,请执行此操作:

void ThisShouldFixIt()
{
  mv.emplace_back(MyClass());
}

请注意,emplace_back可以调用适用的构造函数 如上所述{T} implace below。对于你正在做的事情 push_back很好,但是考虑到一个版本采用右值 参考确实存在。