Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ std::move is bad here?

Let's suppose that I have struct Foo with move constructor and operator=(Foo&&), and I used it as data member:

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

In case (2) I actually not need std::move, but what if I used it here, does this make something bad, like preventing optimization?

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

and find out that changing return foo; to return std::move(foo); cause disabling of RVO, but what about (2) does it cause the similar situation? And if so, why?

like image 567
user1244932 Avatar asked Nov 20 '15 02:11

user1244932


1 Answers

It's 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&, doesn't mean 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 so, if Foo is something that can be iterated over,

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()) forces a non-elidable move, while foo = f() can elide the move from f()'s return value to the argument of operator=.

like image 123
T.C. Avatar answered Sep 30 '22 01:09

T.C.