【问题标题】:Accessing unique_ptrs in std vector - must provide copy constructor?访问 std 向量中的 unique_ptrs - 必须提供复制构造函数?
【发布时间】:2019-06-10 17:12:49
【问题描述】:

我创建了一个标准向量,并使用标准移动将一堆对象推回它上面,例如:

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 以避免实际制作副本,否则它将永远无法工作。我对么? 我想我看过一些关于使用迭代器的帖子,但如果我不必这样做,我宁愿不这样做。

编辑1:

我确实设法通过以下方式解决它(使用迭代器,然后获取原始指针)

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 然后在某处手动释放它。我当然可以暂时转让所有权,直到我完成它然后归还所有权,但这感觉很麻烦。对上述方法有什么想法吗?

提前致谢, /吉米

【问题讨论】:

  • 如果您查看std::unique_ptr 的文档,您会看到是否有几种方法可以返回指针:即release()get() - 阅读它们并决定您想要哪个做,或者直接使用来自myVec[0]的指针,而不是在任何地方复制它。
  • 刚刚发布了一个更新编辑,我使用 get() 方式。我是否正确理解它,这是一种好的方法吗?我猜它“主要”是为了让 unique_ptr 与你必须做的遗留代码一起工作。我的代码是新的,所以我不想在其中有一个丑陋的模式。据我了解,我在 EDIT 部分下的解决方案是正确的。如果不是,我会很乐意学习和纠正它
  • 前提好像是myVec[0]做了个拷贝。它没有。
  • @LightnessRacesinOrbit:你是对的。我一定犯了其他错误,我再次更新了代码,它似乎工作得很好。 Foo* anObj = myVec[0].get() 工作正常。

标签: c++ vector unique-ptr


【解决方案1】:

anObj 变量的类型应为 std::unique_ptr&lt;Foo&gt; 而不是 Foo*

代码应该是:

std::unique_ptr&lt;Foo&gt;&amp; anObj{ myVec[ 0 ] };

或者

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

【讨论】:

  • 使用 [] 运算符不会归结为同样的问题吗?我会收到“...错误:使用已删除的函数 'std::unique_ptr<_tp _dp>::unique_pt...”,因为它尝试使用复制构造函数?
  • 我在这里看不到任何需要复制构造函数的东西。 [] 不复制。如果您现在收到该错误,则说明您没有正确复制 Wbuck 的建议代码。
  • 我一定犯了一些错误,这里的建议工作正常。谢谢大家的帮助
【解决方案2】:

C++ 不会为你决定是使用复制还是引用赋值。

你应该自己处理。

  • 如果您声明新变量并在声明行中使用 = 运算符,例如 int y = x;,则您使用的是复制构造函数。
  • 如果你声明一个变量前面有&amp;,比如int &amp; y = x; 您正在获取x 的引用并将其存储在y 中。

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

  1. 您正在尝试将unique_ptr&lt;Foo&gt; 分配给Foo*,即 不正确。
  2. 您希望拥有unique_ptr&lt;Foo&gt; 引用,以便您 应该像这样声明unique_ptr&lt;Foo&gt; 引用: unique_ptr&lt;Foo&gt; &amp; ref = myVec[0];

【讨论】:

    猜你喜欢
    • 2012-06-20
    • 1970-01-01
    • 1970-01-01
    • 2018-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-19
    相关资源
    最近更新 更多