Should we write `std::move` in the cases when RVO can not be done?
Solution 1:
What happen in your example is not linked to RVO, but to the ternary operator ?
. If you rewrite your example code using an if
statement, the behavior of the program will be the one expected. Change foo
definition to:
Test foo(int param)
{
Test test1;
Test test2;
if (param > 5)
return std::move(test2);
else
return test1;
}
will output Test(Test&&)
.
What happens if you write (param>5)?std::move(test1):test2
is:
- The ternary operator result is deduced to be a prvalue [expr.cond]/5
- Then
test2
pass through lvalue-to-rvalue conversion which causes copy-initialization as required in [expr.cond]/6 - Then the move construction of the return value is elided [class.copy]/31.3
So in your example code, move elision occurs, nevertheless after the copy-initialization required to form the result of the ternary operator.