views:

82

answers:

5

Let's discuss these two functions:

  1. complex& operator+=(const T& val);
  2. complex operator+(const T& val);

Where "complex" is a name of a class that implements for example complex variable.

So first operator returnes reference in order to be possible to write a+=b+=c ( which is equivalent to b=b+c; a=a+b;).

Second operator returnes and objec(NOT A REFERENCE), be we still able to write a=b+c+d.

Who could explain me this nuance? What is the difference between returning reference or object?

+4  A: 

The assignment operators support multiple application to the same object:

(a += b) += c;

Which will add both b and c to a. For this to work, a += b must return a reference to a. The addition operator, however, doesn't require this, since the expression b + c + d has no side-effect. Only the final assignment to a has a side-effect.

Marcelo Cantos
+1  A: 

The nuance is in the examples you give, in a way.

From the + operator you expect to get back a different value from the two you started with: b+c is neither b nor c, it's something else. Thus we can't return references to either b or c ... and short of allocating a new object on the stack those will be the only two we have to work with. Thus we have to return a value.

And you've already explained yourself why the += operator returns what it does.

pycruft
A: 

In the first case, you are adding something to the object on the left, but the value of the expression is the object on the left. So you are returning something (usually the left) by reference. For example:

cout << (a+=b)

In the second case, you are adding two objects and getting a third object, and you can do this calculation on the stack, so you are returning an actual object by value rather than by reference. For example:

if(...)
{
    T a = b + c;
    cout << a;
}
Uri
+1  A: 

Because complex& operator+=(const T& val); operates on this and because complex operator+(const T& val); must create a new temporary object for the sum.

If you were to return an object from +=, it would probably do what you expect, but there might be some extra copies in there. As you mentioned, you would want this behavior if you want to chain calls. If you returned a temporary and wrote (a += b) += c, your addition of c would be lost when it's destroyed in the temporary.

If you were to return a reference from +, you'd have a reference to a temporary and your program would have undefined behavior. You can write a=b+c+d because b+c creates a temporary b1 and b1 + d creates a temporary b2, which is then assigned to a.

Stephen
+1  A: 

In 1, a+=b, the += operator modifies a. Therefore it can return a reference to itself, because a itself is the correct result of the operation.

However, in 2. a new object is required because a+b returns something that is not a, so returning a reference to a wouldn't be correct.

Scott Langham