It's quite simple.
return buffer;
If you do this, then either NRVO will happen or it won't. If it doesn't happen then buffer
will be moved from.
return std::move( buffer );
If you do this, then NVRO will not happen, and buffer
will be moved from.
So there is nothing to gain by using std::move
here, and much to lose.
There is one exception* to the above rule:
Buffer read(Buffer&& buffer) {
//...
return std::move( buffer );
}
If buffer
is an rvalue reference, then you should use std::move
.
This is because references are not eligible for NRVO, so without
std::move
it would result in a copy from an lvalue.
This is just an instance of the rule "always move
rvalue references
and forward
universal references", which takes precedence over the
rule "never move
a return value".
* As of C++20 this exception can be forgotten. Rvalue references in return
statements are implicitly moved from, now.