0

I have seen code that defines a copy assignment operator to return a const reference, e.g.

const MyClass & operator= (const MyClass &);

I'm confused about the intention, and how such operator can be used.

For example, let's say I use it to do something like a = b (a and b are objects of MyClass). Wouldn't that require a to have been declared as const, and if so, wouldn't that mean that I cannot modify a? (i.e. what's the point?)

Amelio Vazquez-Reina
  • 91,494
  • 132
  • 359
  • 564
  • *"Wouldn't that require a to have been declared as const"* No, you can make const references to non-const objects. – HolyBlackCat Dec 31 '22 at 17:16
  • 2
    It breaks the _"least surprise"_ principle, see the expected function signature(s) here - https://en.cppreference.com/w/cpp/language/operator_assignment It will make chain assignments impossible. – Richard Critten Dec 31 '22 at 17:19
  • Thanks @RichardCritten which violates the _"least surprise"_ principle? Using `const` or not using it? (I assume the former?) – Amelio Vazquez-Reina Dec 31 '22 at 17:23
  • @HolyBlackCat but in this case (`a=b`) the compiler would complain unless `a` is `const`, right? and it would also complain even if it was, because we are modifying it, no? – Amelio Vazquez-Reina Dec 31 '22 at 17:26
  • @RichardCritten *"make chain assignments impossible"* It won't. – HolyBlackCat Dec 31 '22 at 17:27
  • @AmelioVazquez-Reina *"would complain unless a is const"* No, that only happens if you add `const` to the right of parameter list. – HolyBlackCat Dec 31 '22 at 17:27
  • Got it @HolyBlackCat , I assume that's because in the case of `a=b` it would use the default copy assignment operator, and not the one I overloaded? Or is it for a different reason? – Amelio Vazquez-Reina Dec 31 '22 at 17:29
  • @HolyBlackCat that's for that. Had to test it - was a surprise. It does stop `(a = b) = c;` but not `a = b = c;` – Richard Critten Dec 31 '22 at 17:31
  • @RichardCritten Mhm, the next assignment in the chain needs the rhs to be `const T &`, and that's exactly what we return. Remember that chain assignments are evaluated right-to-left. – HolyBlackCat Dec 31 '22 at 17:36
  • @AmelioVazquez-Reina No, overloading a copy assignment removes the implicitly generated assignments. There's simply no reason for it to fail. When you `return *this;` in your implementation, constness is implicitly added, and that's it. – HolyBlackCat Dec 31 '22 at 17:38
  • 1
    "The compiler would complain unless `a` is `const`, right?" Why should it? As written, `a = b;` actually requires that `a` _isn't_ `const`, it allows `b` to either be `const` or non-`const`, and it returns a `const` reference. Consider a free function `void print(const std::string& str)`. You wouldn't expect the compiler to complain if you called it on a non-`const` `std::string`, right? – Nathan Pierson Dec 31 '22 at 18:28

0 Answers0