假设我struct Foo
移动constructor
和operator=(Foo&&)
,我将其用作数据成员:
Foo f()
{
Foo foo;
//code
return foo;
}
struct Boo {
Foo foo;
Boo() {
foo = f();//1
foo = std::move(f());//2
}
};
如果(2)我实际上不需要std::move
,
但是,如果我在这里使用它,这会使事情变得糟糕,
喜欢阻止优化?
我读到了这个:Why does std::move prevent RVO?
并发现将return foo;
更改为return std::move(foo);
会导致RVO
停用,但(2)会导致类似情况吗?如果是这样,为什么?
答案 0 :(得分:5)
这是多余和令人困惑的。仅仅因为我可以写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
在您的示例中,如果赋值运算符实现为copy-and-swap(operator=(Foo)
),则foo = std::move(f())
强制执行不可移动的操作,而foo = f()
可以忽略从f()
的返回值移至operator=
的参数。