Search code examples
c++move-semanticsreturn-value-optimization

When to rely on RVO vs move semantics in C++?


Say I have some expensive class X, and take this code:

X functor() {
    X x;
    //do stuff
    return x;
}

int main() {
    std::vector<X> vec;
    vec.push_back(functor());
    vec.push_back(std::move(functor()));

    return 0;
}

Which push_back is more efficient? In the first case, won't the NRVO be activated and prevent the copy as the move does? Should I be relying on the NRVO instead of doing manual moving, since the NRVO is basically automatic moving?


Solution

  • Neither piece of code is more efficient; they do the exact same thing. And neither push_back expression involves elision of any kind. The only actual elision happened back in the return statement, which the push_back expressions don't interact with.

    In both push_back expressions, the prvalue returned by the function will manifest a temporary. In the latter case, the temporary will be cast into an xvalue, but that doesn't represent any actual runtime changes. Both versions will call the same push_back overload: the one which takes an rvalue reference. And therefore in both cases the return value will be moved from.