Recently I have read that it makes sense when returning by value from a function to qualify the return type const for non-builtin types, e.g.:
const Result operation() { //..do something.. return Result(..); }
I am struggling to understand the benefits of this, once the object has been returned surely it's the callers choice to decide if the returned object should be const?
In the hypothetical situation where you could perform a potentially expensive non-const operation on an object, returning by const-value prevents you from accidentally calling this operation on a temporary.
If you say that a function's return value is const: const int g(); you are promising that the original variable (inside the function frame) will not be modified. And again, because you're returning it by value, it's copied so the original value could never be modified via the return value.
Declaring a member function with the const keyword specifies that the function is a "read-only" function that doesn't modify the object for which it's called. A constant member function can't modify any non-static data members or call any member functions that aren't constant.
Basically, there's a slight language problem here.
std::string func() { return "hai"; } func().push_back('c'); // Perfectly valid, yet non-sensical
Returning const rvalues is an attempt to prevent such behaviour. However, in reality, it does way more harm than good, because now that rvalue references are here, you're just going to prevent move semantics, which sucks, and the above behaviour will probably be prevented by the judicious use of rvalue and lvalue *this
overloading. Plus, you'd have to be a bit of a moron to do this anyway.
It is occasionally useful. See this example:
class I { public: I(int i) : value(i) {} void set(int i) { value = i; } I operator+(const I& rhs) { return I(value + rhs.value); } I& operator=(const I& rhs) { value = rhs.value; return *this; } private: int value; }; int main() { I a(2), b(3); (a + b) = 2; // ??? return 0; }
Note that the value returned by operator+
would normally be considered a temporary. But it's clearly being modified. That's not exactly desired.
If you declare the return type of operator+
as const I
, this will fail to compile.
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