Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should post increment operator overloading in c++ return const data type [duplicate]

Tags:

c++

constants

What is the purpose of the const in this?

const Object myFunc(){
    return myObject;
}

I've just started reading Effective C++ and Item 3 advocates this and a Google search picks up similar suggestions but also counterexamples. I can't see how using const here would ever be preferable. Assuming a return by value is desirable, I don't see any reason to protect the returned value. The example given for why this might be helpful is preventing unintended bool casts of the return value. The actual problem then is that implicit bool casts should be prevented with the explicit keyword.

Using const here prevents using temporary objects without assignment. So I couldn't perform arithmetic expressions with those objects. It doesn't seem like there's ever a case that an unnamed const is useful.

What is gained by using const here and when would it be preferable?

EDIT: Change arithmetic example to any function that modifies an object that you might want to perform before an assignment.

like image 906
Praxeolitic Avatar asked Nov 23 '22 14:11

Praxeolitic


2 Answers

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. Imagine that + returned a non-const value, and you could write:

(a + b).expensive();

In the age of C++11, however, it is strongly advised to return values as non-const so that you can take full advantage of rvalue references, which only make sense on non-constant rvalues.

In summary, there is a rationale for this practice, but it is essentially obsolete.

like image 79
Kerrek SB Avatar answered Feb 17 '23 11:02

Kerrek SB


It's pretty pointless to return a const value from a function.

It's difficult to get it to have any effect on your code:

const int foo() {
   return 3;
}

int main() {
   int x = foo();  // copies happily
   x = 4;
}

and:

const int foo() {
   return 3;
}

int main() {
   foo() = 4;  // not valid anyway for built-in types
}

// error: lvalue required as left operand of assignment

Though you can notice if the return type is a user-defined type:

struct T {};

const T foo() {
   return T();
}

int main() {
   foo() = T();
}

// error: passing ‘const T’ as ‘this’ argument of ‘T& T::operator=(const T&)’ discards qualifiers

it's questionable whether this is of any benefit to anyone.

Returning a reference is different, but unless Object is some template parameter, you're not doing that.

like image 27
Lightness Races in Orbit Avatar answered Feb 17 '23 10:02

Lightness Races in Orbit