在标准向量中访问unique_ptrs-必须提供复制构造函数吗?

时间:2019-06-10 17:12:49

标签: c++ vector unique-ptr

我已经创建了一个std向量,并使用std移动将一堆对象推回其上,例如:

vector<unique_ptr<Foo> > myVec;
unique_ptr<Foo> a = make_unique<Foo>();
unique_ptr<Foo> b = make_unique<Foo>();
myVec.push_back(move(a));
myVec.push_back(move(b));

到目前为止,很好。

稍后,我将myVec的引用传递给函数,并尝试使用[]运算符访问向量中的数据。

void someFunc(vector<unique_ptr<Foo> > &myVec)
{
    Foo* anObj = myVec[0];
}

经过一番阅读之后,我的猜测是这种方法行不通,因为std向量将尝试创建一个副本,除非我在Foo上提供了一个copyconstructor,以避免实际制作一个副本,否则它将永远无法工作。我对么? 我想我看到了一些有关使用迭代器的文章,但是我宁愿不要,如果不需要的话。

EDIT1:

我确实设法解决了以下问题(使用迭代器,然后获取原始指针)

void someFunc(vector<unique_ptr<Foo> > &myVec)
{
    int offset = 0; // Or some other offset into the vector
    auto it = myVec.begin() + offset;
    Foo* anObj = it.get();
    // ... Do something using anObj here...
}

我认为这是可行的方法,只要您不要愚蠢地尝试保留anObj,然后在某个地方手动释放它即可。当然,我可以临时转移所有权,直到Im完成后再归还所有权,但这感觉很麻烦。对上述方法有何想法?

预先感谢, /吉米

2 个答案:

答案 0 :(得分:3)

anObj变量应为std::unique_ptr<Foo>类型,而不是Foo*

代码应为:

std::unique_ptr<Foo>& anObj{ myVec[ 0 ] };

Foo* anObj{ myVec[ 0 ].get( ) };

答案 1 :(得分:0)

C ++不决定是否使用复制或引用分配。

您应该自己处理。

  • 如果您声明新变量,并在声明行中使用=之类的int y = x;运算符,那么您正在使用复制构造函数。
  • 如果您声明的变量前面有&,例如int & y = x; 您将引用x并将其存储在y中。

在您的示例中,您有2个问题:

  1. 您正在尝试将unique_ptr<Foo>分配给Foo* 不正确
  2. 您希望拥有unique_ptr<Foo>参考,以便您 应该声明unique_ptr<Foo>这样的引用: unique_ptr<Foo> & ref = myVec[0];