C ++ std :: move is bad here?

Suppose I have a struct Foo with move constructor and operator=(Foo&&) , and I used it as a data element:

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

In case (2), I really don't need std::move , but what if I used it here, it does something bad, like preventing optimization?

I read this: Why does std :: move prevent RVO?

and find out that change return foo; on return std::move(foo); RVO , but what about (2) does this situation? And if so, why?

+5
source share
1 answer

This is redundant and confusing. Just because I can write std::add_pointer_t<void> instead of void* or std::add_lvalue_reference_t<Foo> (or Foo bitand ) instead of Foo& does not mean that I should.

It also matters in other contexts:

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

and therefore, if Foo is something that can be repeated,

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

And in your example, if the assignment operator is implemented as copy-and-swap ( operator=(Foo) ), then foo = std::move(f()) forcibly executes a non-elite move, while foo = f() can overcome the transition of f() return the value for the operator= argument.

+5
source

Source: https://habr.com/ru/post/1236391/


All Articles