c++ std::move 在这里不好吗?
c++ std::move is bad here?
假设我有 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) 会导致类似情况?如果是,为什么?
这是多余的和令人困惑的。仅仅因为我可以写 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()
的 return 值到 operator=
.
的参数的移动
假设我有 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) 会导致类似情况?如果是,为什么?
这是多余的和令人困惑的。仅仅因为我可以写 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()
的 return 值到 operator=
.