Search code examples
c++11copymove-semanticsreturn-by-referencereturn-by-value

Optimal way to return local value in C++11


In the old days, if I wanted a string representation of an object A, I would write something with the signature void to_string(const A& a, string& out) to avoid extra copies. Is this still the best practice in C++11, with move semantics and all?

I have read several comments on other contexts that suggest relying on RVO and instead writing string to_string(const A& a). But RVO is not guaranteed to happen! So, how can I, as the programmer of to_string, guarantee the string is not copied around unnecessarily (independently of the compiler)?


Solution

  • Here is the answer I gathered from feedback and other resources:

    The straightforward return by value is the idiom because:

    • in practice copy/move elision will take place most of the time;
    • the move ctor will be used on fallback;
    • preventing the improbable case of a copy actually happening is not worth the less readable code
    • passing the reference in requires the object to have already been created
      • not always feasible (for instance, there might be no default ctor) and which
      • one initialization too much also has to be taken into account if the issue is performance

    However, if the typical usage is anticipated to be something like

    std::string s;
    while (i_need_to)
    {
        to_string(get_A(), s);
        process(s);
        update(i_need_to);
    }
    

    and if the type in question has a default constructor*, then it may still make sense to pass the object that should hold the return by reference.

    *considering string here only as an example, but the question and answers could be generalized