Passing by value vs const & and && overloads

As you can see, ByVal produces 1 extra move compared to pair of
reference overloads. So the question is: is it worth it? When would
you create two overloads instead of one simple pass by value function?

+1 Most people who ask this question don’t bother to do the analysis. So you get my upvote for doing your own homework. 🙂

Whether it is worth it or not is going to depend on the cost of the move constructor, and on how many arguments the function takes. On one extreme, if the move constructor isn’t that fast, you may care a lot about eliminating them (favoring the const&, && overload solution). At the other extreme, if your function has 4 parameters, each of which need lvalue/rvalue treatment, you may not be willing to write 16 overloads to cover all the cases. That’s a lot of code to maintain, and the inherent code complexity is an invitation for bugs. So the by-value approach looks more attractive (which requires no overloads).

So imho, there is no general answer to the “is it worth it” question. The best answer is to equip yourself with the knowledge about the cost of each solution, as you have already done, and make an engineering judgement on a case by case basis.

Update

In the case of vector<T>::push_back imho the const&, && overload solution is worth it. There is only one parameter, and we have no idea how expensive the move constructor is. Indeed, we don’t even know if there is a move constructor. Modifying your experiment to test out that latter case (removing the move constructor):

ByVal(a);
A Copy
A Copy

ByLCRef(a);
A Copy

Do you want to pay one copy or two to copy your A into the vector?

I.e. the less you know about your parameters, the more you have to lean towards the performance side, especially if you’re writing something as heavily used as std::vector.

Leave a Comment

tech