The simple answer is: yes.
The reason is quite simple as well, if you store by value you might either need to move (from a temporary) or make a copy (from a l-value). Let us examine what happens in both situations, with both ways.
From a temporary
- if you take the argument by const-ref, the temporary is bound to the const-ref and cannot be moved from again, thus you end up making a (useless) copy.
- if you take the argument by value, the value is initialized from the temporary (moving), and then you yourself move from the argument, thus no copy is made.
One limitation: a class without an efficient move-constructor (such as std::array<T, N>
) because then you did two copies instead of one.
From a l-value (or const temporary, but who would do that...)
- if you take the argument by const-ref, nothing happens there, and then you copy it (cannot move from it), thus a single copy is made.
- if you take the argument by value, you copy it in the argument and then move from it, thus a single copy is made.
One limitation: the same... classes for which moving is akin to copying.
So, the simple answer is that in most cases, by using a sink you avoid unnecessary copies (replacing them by moves).
The single limitation is classes for which the move constructor is as expensive (or near as expensive) as the copy constructor; in which case having two moves instead of one copy is "worst". Thankfully, such classes are rare (arrays are one case).
const&
and then initializing will call a single copy constructor. Passing by value and moving will call a copy constructor followed by a move assignment operator. – Santalaceous