【问题标题】:Passing vector of unique_ptr with move semantics in c++在 C++ 中使用移动语义传递 unique_ptr 的向量
【发布时间】:2020-12-23 22:17:12
【问题描述】:

我正在学习 CPP++14 移动语义。在编写小代码时,我观察到一些奇怪的行为。我正在使用 r 值引用将唯一 ptr 的向量移动到函数中。在调试时,我发现更改也应用于移动的对象。为什么即使物体被移动,我也会观察到这种情况?以下代码中的移动有什么作用?

void func(std::vector<std::unique_ptr<int>> && vect) {
    vect.emplace_back(std::move(std::make_unique<int>(3)));
    return ;
}

int  main() {
    std::vector<std::unique_ptr<int>> a;
    func(std::move(a));
    cout<<(*(a[0]))<<endl;
    return 0;
}

【问题讨论】:

  • 你没有移动任何东西。您只是通过右值引用传递对象。此举只不过是在您的代码中进行强制转换。
  • @super 如果问题有用且符合主题,请不要在 cmets 中回答。
  • This 应该有助于您理解移动语义。您可能还想考虑让自己成为good C++ book
  • @πάνταῥεῖ - 如果你写一个简短的答案,它会自动转换为评论。
  • @Den-Jason Ah ty。我不知道。应该是最近改的。我已经离开元训练营一年了 ;-)

标签: c++ stdvector unique-ptr stdmove


【解决方案1】:

移动在下面的代码中有什么作用?

func(std::move(a));中并没有进行移动操作,实际上std::move只是进行了转换,并产生了一个右值(xvalue)表达式,它只是绑定到func的右值引用参数vect。那么在func 中对vect 的任何修改也会对参数(即a)产生影响,它们指的是同一个对象。

特别是,std::move 生成一个 xvalue 表达式来标识其参数 t。它完全等同于 static_cast 到右值引用类型。

如果您将参数更改为按值传递,那么您将看到执行了移动操作。鉴于您展示的用法,仅传递左值引用似乎不那么令人困惑(并且无需再次在参数上使用std::move)。

顺便说一句:在vect.emplace_back(std::move(std::make_unique&lt;int&gt;(3))); 中,std::move 的使用是多余的,std::make_unique&lt;int&gt;(3) 是一个右值表达式。

【讨论】:

  • @NathanOliver 值类别是表达式的属性,而不是类型。 move(a) 作为表达式是一个右值。
  • @asheeshkumarsinghal 您的代码适合您展示的用法;这只是令人困惑。在这里只传递左值引用似乎更好。
  • @asheeshkumarsinghal 如果您按值获取向量,它将被移动。通过引用传递某些东西不会移动它。引用只是指原始的东西。
  • @asheeshkumarsinghal 不,这与 a 用于这种情况无关。它只是绑定到参考参数。如果您创建一个从右值复制的新对象,则会发生移动操作。
  • @asheeshkumarsinghal 是的,它只是一个参考,当退出函数时会被销毁。请注意,它引用的对象(即a)不会被破坏。
猜你喜欢
  • 2013-04-07
  • 2021-07-24
  • 1970-01-01
  • 1970-01-01
  • 2023-03-29
  • 2014-07-21
  • 2019-11-08
  • 2015-10-03
  • 2019-07-14
相关资源
最近更新 更多