4

I'm a little confused as to why I've been told to return const foo from a binary operator in c++ instead of just foo.

I've been reading Bruce Eckel's "Thinking in C++", and in the chapter on operator overloading, he says that "by making the return value [of an over-loading binary operator] const, you state that only a const member function can be called for that return value. This is const-correct, because it prevents you from storing potentially valuable information in an object that will be most likely be lost".

However, if I have a plus operator that returns const, and a prefix increment operator, this code is invalid:

class Integer{
int i;

public:
    Integer(int ii): i(ii){ }
    Integer(Integer&);

    const Integer operator+();
    Integer operator++();
};


int main(){

Integer a(0);
Integer b(1);

Integer c( ++(a + b));
}

To allow this sort of assignment, wouldn't it make sense to have the + operator return a non-const value? This could be done by adding const_casts, but that gets pretty bulky, doesn't it?

Thanks!

4 Answers 4

4

When you say ++x, you're saying "add 1 to x, store the result back into x, and tell me what it was". This is the preincrement operator. But, in ++(a+b), how are you supposed to "store the result back into a+b"?

Certainly you could store the result back into the temporary which is presently holding the result of a+b, which would vanish soon enough. But if you didn't really care where the result was stored, why did you increment it instead of just adding one?

Sign up to request clarification or add additional context in comments.

Comments

4

FYI, ++(a + b) is illegal even with PODs (plain old data types, like int). So it makes sense not to allow it for your own class types either. Try this:

int a = 1;
int b = 2;
int c = ++(a+b);

GCC returns error: lvalue required as increment operand.

In your case, it would be preferable make your copy constructor take a const Integer argument, and create your Integer c like this instead:

Integer c(a + b + Integer(1));

Comments

0

Copy constructors usually take a const reference, solving that problem for you.

(Having non-const copy ctor implies some transfer of resources, which can be useful sometimes, but for 99% of all situations, it's not needed)

Comments

0

I believe OP's example would be suitable to the question if the addition operator is substituted with any other binary operator that returns a reference, for example an assignment operator:

Integer c( ++(a = b));

I came here wondering whether I should make my assignment operator return a const or a non-const reference. Some tutorials use non-const versions, contrary to "Thinking in C++"'s advice. And some other references give reasoning behind that:

Notice that the returned reference is not declared const. This can be a bit confusing, because it allows you to write crazy stuff like this:

MyClass a, b, c;

...

(a = b) = c; // What??

At first glance, you might want to prevent situations like this, by having operator= return a const reference. However, statements like this will work with primitive types. And, even worse, some tools actually rely on this behavior. Therefore, it is important to return a non-const reference from your operator=. The rule of thumb is, "If it's good enough for ints, it's good enough for user-defined data-types."

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.