Taking by copy is done to enable a specific idiom, when +
is implemented in terms of +=
:
inline X operator+(X lhs, const X& rhs) {
lhs += rhs;
return lhs;
}
On the other hand, if you take lhs
by const X&
reference, you would have to either make a copy yourself, like this
inline X operator+(const X& lhs, const X& rhs) {
X res(lhs);
res += rhs;
return res;
}
or to construct a new object, like this:
inline X operator+(const X& lhs, const X& rhs) {
X res;
... // Modify res to contain the sum of lhs and rhs
return res;
}
If you are using the idiomatic approach, the compiler can optimize chains of +
for you by making a copy once. The compiler notices that when you do this
lhs + rhs1 + rhs2
the result of lhs + rhs1
is a throw-away copy which can be reused in constructing (lhs + rhs1) + rhs2
without performing a copy again.
On the other hand, if you use one of the alternatives above, the compiler would need to make a copy for each operation in the chain.