【问题标题】:Use of std::move in parameter construction在参数构造中使用 std::move
【发布时间】:2015-11-30 11:29:48
【问题描述】:

我正在尝试从一个函数构造一个对象,然后将它传递给一个使用它(并使用它)的函数。这是代码

std::unique_ptr<Object> createObject() {
  auto myobj = std::make_unique<Object>();
  .. modify myobj ..
  return std::move(myobj);
}

void consumeObject(std::unique_ptr<Object>&& robj) {
  myvector.emplace_back(std::forward<std::unique_ptr<Object>>(robj));
}


consumeObject(createObject()); // Is this right?

我没有直接使用来自createObject 的右值引用,因为我会返回对已释放内存的引用。

std::move 在代码中指示的部分是否必要?如果像我在上面的代码中所做的那样,我传递一个右值以绑定到右值引用会发生什么?代码似乎编译得很好,但我看不出 a 之间的区别

consumeObject(createObject());

consumeObject(std::move(createObject()));

【问题讨论】:

  • 您的代码错误:createObject 返回 unique_ptr&lt;Object&gt;,但 consumeObject 采用 Object。你能解决这个问题吗?
  • return std::move(myobj); 中的移动禁止 NRVO,只需执行return myobj;
  • 您应该使用 MCVE 进行实际测试。否则有什么意义呢? (郑重声明,这不是 MCVE。)
  • std::forward 在这种情况下零意义(并且您忘记在问题中更改其模板参数)。 std::move 就可以了。
  • @LightnessRacesinOrbit 我主要是想开个玩笑。我对移动语义的无知感到非常无聊和沮丧

标签: c++ c++11 rvalue-reference rvalue


【解决方案1】:

std::move 没有做任何神奇的事情,它只是将参数转换为右值。

由于createObject 按值返回,createObject() 已经是一个右值(特别是纯右值),所以在这种情况下std::move 是不必要的,您可以放心地省略它。

【讨论】:

  • std::move 的完全混乱的命名选择再次来袭。
【解决方案2】:
std::unique_ptr<Object> createObject() {
  auto myobj = std::make_unique<Object>();
  .. modify myobj ..
  return std::move(myobj);
}

您不需要std::move 按值返回本地、仅移动对象。

void consumeObject(std::unique_ptr<Object>&& robj) {
  myvector.emplace_back(std::forward<std::unique_ptr<Object>>(robj));
}

使用std::forward 没有任何意义*,除非您使用所谓的“转发引用”,而您不在这里。仅仅拥有&amp;&amp; 并不意味着您应该使用std::forward。此外,这里根本不需要&amp;&amp;

consumeObject(createObject()); // Is this right?

是的。


这可能是代码应该看起来的样子。请注意,您通常避免使用任何 C++11 特定语法,而是代码看起来与按值传递可复制对象几乎相同。这里只有一个地方需要任何新的东西。

std::unique_ptr<Object> createObject() {
  auto myobj = std::make_unique<Object>();
  .. modify myobj ..
  return myobj;
}

void consumeObject(std::unique_ptr<Object> robj) {
  myvector.emplace_back(std::move(robj));
}


consumeObject(createObject());

* std::forwardstd::move 都只是演员表,而您在此处使用 std::forward 的方式恰好适合正确的演员表以获得移动构造。但是为了可读性,应该只使用std::move 移动,只使用std::forward 转发。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2013-12-08
  • 2014-04-15
  • 2022-12-23
  • 2015-02-14
  • 1970-01-01
  • 1970-01-01
  • 2014-03-13
  • 2013-01-22
相关资源
最近更新 更多