In general, it depends on the cost of copying and moving for a certain type (and even objects) and how it is called (with temporary or not, etc.)
For example, for temporary boo(gimme_t()) :
Let d be the depth of the tree of your classes
Solution with move cost d * COST_OF_MOVE , solution with COST_OF_COPY + d * REF_ASSIGNMENT .
You can see that for std::string it O(d) vs O(n) so for strings with a long length it is cheaper to use moves (and for short strings this is not so important), but for std::array<int> it's O(nd) vs O(n + d) , so you better use a single copy.
But if the argument is not temporary ( T t; boo(t) ), the costs will be:
COST_OF_COPY + d * COST_OF_MOVE vs COST_OF_COPY + d * REF_ASSIGNMENT , so the const-ref solution is faster by d .
But if you can consider move almost free ™, you better use a move solution to avoid 1 copy in case of a temporary argument
(*) Everywhere you have to read d ± 1 instead of d
Riad
source share