c++std::move在这里不好

c++ std::move is bad here?

本文关键字:move c++std 在这里      更新时间:2023-10-16

让我们假设我有struct Foo和move constructoroperator=(Foo&&),并将其用作数据成员:

Foo f()
{
  Foo foo;
  //code
  return foo; 
}
struct Boo {
Foo foo;
Boo() {
  foo = f();//1
  foo = std::move(f());//2
}
};

(2)的情况下,我实际上不需要CCD_,但如果我在这里用它,会不会有什么不好的地方,比如阻止优化?

我读到这篇文章:为什么std::move可以防止RVO?

并发现将return foo;更改为return std::move(foo);会导致RVO禁用,但(2)会导致类似情况吗?如果是,为什么?

它是多余的并且令人困惑。仅仅因为我可以用std::add_pointer_t<void>代替void*,或者用std::add_lvalue_reference_t<Foo>(或Foo bitand)代替Foo&,并不意味着我应该这样做。

它在其他情况下也很重要:

auto&& a = f(); // OK, reference binding to a temporary extends its lifetime
auto&& b = std::move(f()); // dangling

因此,如果Foo是可以迭代的东西,

for(const auto& p : f()) {} // OK
for(const auto& p : std::move(f())) {} // UB

在您的示例中,如果赋值运算符实现为复制和交换(operator=(Foo)),则foo = std::move(f())强制执行不可消除的移动,而foo = f()可以消除从f()的返回值到operator=的参数的移动。