You should think of this in terms of what is being initialized from what.
When you call a function, each argument is used to initialize the corresponding parameter. If the parameter is declared with reference type, it's a reference. If the parameter is not declared with reference type, it's an object.
- The initialization of a reference to class type
T
from an expression of type T
never makes a copy.
- The initialization of an object of class type
T
from an expression of type T
either copies or moves.
The rules here are the same as the rules for initializing non-parameter variables, as in:
T t = ...
T& r = ...
The fact that a function may take a reference to an argument even when there is no explicit notation at the call site is viewed by some as confusing. This is why some style guides ban non-const
reference parameters (such as the Google C++ style guide) and force you to declare the argument as a pointer so that &
must be used at the call site. I don't advocate this coding style, but it is an option you might want to consider.