It can be more efficient, for example, in a bit different context:
template <typename T>
T&& min_(T&& a, T &&b) {
return std::move(a < b? a: b);
}
int main() {
const std::string s = min_(std::string("A"), std::string("B"));
fprintf(stderr, "min: %s\n", s.c_str());
return 0;
}
As an interesting observation, on my machine clang++ -O3 generates 54 instructions for code above versus 62 instructions for regular std::min. However, with -O0 it generates 518 instructions for code above versus 481 for regular std::min.
This returns a dangling reference, just like with the lvalue reference case. After the function returns, the temporary object will get destructed. You should return Beta_ab by value, like the following
Now, it's properly moving a temporary Beta_ab object into the return value of the function. If the compiler can, it will avoid the move altogether, by using RVO (return value optimization). Now, you can do the following
Beta_ab ab = others.toAB();
And it will move construct the temporary into ab, or do RVO to omit doing a move or copy altogether. I recommend you to read BoostCon09 Rvalue References 101 which explains the matter, and how (N)RVO happens to interact with this.
Your case of returning an rvalue reference would be a good idea in other occasions. Imagine you have a getAB() function which you often invoke on a temporary. It's not optimal to make it return a const lvalue reference for rvalue temporaries. You may implement it like this
Note that move in this case is not optional, because ab is neither a local automatic nor a temporary rvalue. Now, the ref-qualifier&& says that the second function is invoked on rvalue temporaries, making the following move, instead of copy
It can be more efficient, for example, in a bit different context:
As an interesting observation, on my machine
clang++ -O3
generates 54 instructions for code above versus 62 instructions for regularstd::min
. However, with-O0
it generates 518 instructions for code above versus 481 for regularstd::min
.This returns a dangling reference, just like with the lvalue reference case. After the function returns, the temporary object will get destructed. You should return
Beta_ab
by value, like the followingNow, it's properly moving a temporary
Beta_ab
object into the return value of the function. If the compiler can, it will avoid the move altogether, by using RVO (return value optimization). Now, you can do the followingAnd it will move construct the temporary into
ab
, or do RVO to omit doing a move or copy altogether. I recommend you to read BoostCon09 Rvalue References 101 which explains the matter, and how (N)RVO happens to interact with this.Your case of returning an rvalue reference would be a good idea in other occasions. Imagine you have a
getAB()
function which you often invoke on a temporary. It's not optimal to make it return a const lvalue reference for rvalue temporaries. You may implement it like thisNote that
move
in this case is not optional, becauseab
is neither a local automatic nor a temporary rvalue. Now, the ref-qualifier&&
says that the second function is invoked on rvalue temporaries, making the following move, instead of copy