Search code examples
c++performancec++11lifetimetemporary-objects

Which is better to get return value, by const&, by &&, or just by value?


#include <vector>

std::vector<int> f()
{
    return std::vector<int>(1024);
}

void use_1(std::vector<int> const&)
{}

void use_2(std::vector<int> const&)
{}

int main()
{
    {
        auto const& v = f(); // style 1
        use_1(v);
        use_2(v);
    }

    {
        auto&& v = f(); // style 2
        use_1(v);
        use_2(v);
    }

    {
        auto v = f(); // style 3
        use_1(v);
        use_2(v);
    }
}

Which is better? style 1, style 2, or style 3?

In my opinion, if the return type doesn't implement move-semantics, then style 1 and style 2 are more efficient than style 3.


Solution

  • By-value won't be wrong and it's no-less efficient. The life-time is clear, it won't ever dangle. Reference versions are error-prone. Take this example:

    #include <utility>
    
    struct Bar {};
    
    template <class T>
    auto&& foo(T&& t) {
      return std::forward<T>(t);
    }
    
    int main() { 
      auto&& bar = foo(Bar{});
      // bar dangles
    }
    

    You may think "this will never happen" but as the code base gets more complicated it does happen. Keep it simple.