The "Effective C++" Item 3 says "Use const whenever possible", and it gives an example like:
const Rational operator*(const Rational& lhs, const Rational& rhs);
to prevent clients from being able to commit atrocities like this:
Rational a, b, c; ... (a * b) = c; // invoke operator= on the result of a*b!
But isn't the non-reference return value of functions allready a rvalue? So why bother doing this?
The point is that for class types (but not for builtin types), a = b
is just a shorthand to a.operator=(b)
, where operator= is a member function. And member functions can be called on rvalues such (a * b)
created by Rational::operator*
. To enforce similar semantics as for builtin rvalues ("do as the ints do") some authors (Meyers including) recommended in C++98 to return by const-rvalue for classes with such operators.
However, in C++11 returning by const-rvalue is a bad idea as it will inhibit move semantics because const rvalues cannot bind to T&&
.
In his notes An overview of the new C++ (C++11), Scott Meyers gives precisely the same example from his old book, and concludes that it is now considered poor design to add the const return value. The recommended signature is now
Rational operator*(const Rational& lhs, const Rational& rhs);
UPDATE: As implied by @JohannesSchaub-litb in the comments, in C++11 you can also use a reference qualifier on the assignment operator so that it will only accept lvalues as its left argument (i.e. the *this
pointer, which is why this feature is also known as "rvalue references for *this"). You'll need g++ >= 4.8.1 (just released) or Clang >= 2.9 to make use of it.
The const modifier on the return value is not necessary and can hinder move semantics. The preferred way of preventing assignment to rvalues in C++11 is to use "ref-qualifiers."
struct Rational { Rational & operator=( Rational other ) &; // can only be called on lvalues }; Rational operator*( Rational const & lhs, Rational const & rhs ); Rational a, b, c; (a * b) = c; // error
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With