Prior to C++11, if I had a function that operated on large objects, my instinct would be to write functions with this kind of prototype.
void f(A &return_value, A const ¶meter_value);
(Here, return_value is just a blank object which will receive the output of the function. A is just some class which is large and expensive to copy.)
In C++11, taking advantage of move semantics, the default recommendation (as I understand it) is the more straightforward:
A f(A const ¶meter_value);
Is there ever still a need to do it the old way, passing in an object to hold the return value?
Others have covered the case where
Amight not have a cheap move constructor. I’m assuming yourAdoes. But there is still one more situation where you might want to pass in an “out” parameter:If
Ais some type likevectororstringand it is known that the “out” parameter already has resources (such as memory) that can be reused withinf, then it makes sense to reuse that resource if you can. For example consider:vs:
In the first case, capacity will build up in the
stringas the loop executes, and that capacity is then potentially reused on each iteration of the loop. In the second case a newstringis allocated on every iteration (neglecting the small string optimization buffer).Now this isn’t to say that you should never return
std::stringby value. Just that you should be aware of this issue and apply engineering judgment on a case by case basis.