2

I have a theoretical question:

Usually, in an operator= implementation, it returns *this. But what happens if we instead returned *other, where other is the right hand side of the assignment?

Thanks

  • 3
    Usually you won't be even able to return `other`, because the rhs of the assignment operator is correctly declared as `const` reference parameter. – πάντα ῥεῖ Jun 26 '14 at 15:52
  • 3
    What will happen is that other people reading your code will wonder what on Earth made you think that is a good idea. – Casey Jun 26 '14 at 15:55
  • 3
    You as the programmer have the freedom to break any and all conventions, but don't be surprised if that makes others hate you. Actually, a few minutes later you'll probably deservedly fall into your self-dug pit. Also see: [Operator overloading](https://stackoverflow.com/questions/4421706/operator-overloading) – Deduplicator Jun 26 '14 at 15:59
  • 2
    It's an interesting idea. It's not quite as bad as `#define while if`, but it's more or less along the same lines. It should lead to some interesting debugging sessions for someone down the line. – James Kanze Jun 26 '14 at 16:02
  • 2
    `#define if(X) if(rand() && (X))` – Mooing Duck Jun 26 '14 at 16:17

3 Answers3

0

The purpose of returning *this from the assignment operator is to allow for assignment chaining, e.g.

int x = 2;
int y = x = 5; // Equivalent to: 'int y = (x = 5);'

The copy assignment operator is usually declared as:

T& operator=(const T& other);

Here the argument other is declared as const and can thus not be returned. Returning by const T& will also act differently as the caller can not assign to the returned reference, thus disallowing assignment chaining.

Often you will also assign with a temporary. If you customize the behaviour of the assignment operator to return a reference to this temporary it can result in dangling references and other dangerous behaviours.

std::string s;
(s = "abc") = "def"; // Can't assign to rhs.

It is possible to customize the behaviour of the assignment operator to achieve different behaviours, but you should generally refrain from doing so to keep the meaning of the operator clear. If you want custom behaviour it's better to provide a function with a good descriptive name.

More info about operator overloading can be found here.

Community
  • 1
  • 1
Felix Glas
  • 15,065
  • 7
  • 53
  • 82
0

Reason for returning *this is to enable assignment in this form

a = b = c

this is same as

a.operator=( b.operator=(c))

If you return other, compiler wont be able to compile this kind of assignments.

PankajM
  • 417
  • 2
  • 10
  • 5
    Of course you'll be able to execute it. It will compiler without error and will run without crashing. Of course, it won't do anything near what any reasonable person would expect, but that's another issue. – James Kanze Jun 26 '14 at 16:00
  • @JamesKanze: Actually, since they should be equivalent at that point, I doubt it would have any side effects, unless passed to a function by reference and the function takes the address. – Mooing Duck Jun 26 '14 at 16:38
0

Well their will be two factual differences :

  • You will be forced to return a reference to a const instance from your operator= or a copy
  • You assignment will return a reference on its right hand side instead of its left hand side

Mostly what this means is you will surprise some developers that might exploit the return value of your assignment thinking it gives back the left hand side as most objects do.

But there is not so many people who sanely intend to write things like:

(a = b).do_action();

And since you just assigned the right value to the left one and you are returning either a const instance or a copy, most of the operations will most likely result in the same thing no matter if they are called on the left or right instance. So basically most of the time it won't change anything to your life.

However except if you are a boost::spirit developer, you are highly encouraged to avoid such things for the sanity of your colleagues :)

Drax
  • 12,682
  • 7
  • 45
  • 85