11

According to replies to this thread, operator= cannot be overloaded as a non-member function. So, for example, the following makes the compiler very angry:

class MyClass
{
    // ...
};

MyClass& operator=(MyClass& Left, MyClass& Right)
{
    // ...
}

Why is this? I have a container class with getters and setters, so a member function is unnecessary and it would break encapsulation. One of the answers to the aforementioned thread said that it's to make sure the "L-value is received as its first operand," but I don't fully understand what that means. Could someone please clarify?

Additionally, are operator=, operator(), operator[] and operator-> "oddball" cases...? Or should I implement all overloaded operators as member functions...? (I know it's perfectly legal to do otherwise, but I'm looking for the better practice.)

curiousguy
  • 8,038
  • 2
  • 40
  • 58
Maxpm
  • 24,113
  • 33
  • 111
  • 170
  • 1
    Also see this thread http://stackoverflow.com/questions/3938036/rationale-of-enforcing-some-operators-to-be-members – UmmaGumma Mar 21 '11 at 16:45
  • I think getters/setters break encapsulation more than an assignment operator. Note: If if you do not define one your class already has an assignment operator. Try it. – Martin York Mar 21 '11 at 16:50
  • Member functions don't break encapsulation; they're a part of it. The preference to create "non-member, non-friend functions" can result in simpler classes, but in the general case, exposing everything necessary to implement operator=() is more likely to weaken encapsulation than making operator=() a member. – Andy Thomas Mar 21 '11 at 16:54
  • 1
    Answered here: http://stackoverflow.com/questions/3933637/why-friend-function-cant-be-used-for-overloading-assignment-operator – AnT stands with Russia Mar 21 '11 at 16:54

2 Answers2

6

If your class doesn't have an assignment operator (as a member), the compiler generates one by default, just like it generates a copy constructor if you don't provide one.

Therefore it will be "angry" if you try to define a non-member assignment operator later. There will then be two!

Bo Persson
  • 90,663
  • 31
  • 146
  • 203
  • The rule could simply be changed to try to find a non-member one first. – GManNickG Mar 21 '11 at 16:40
  • @GMan What if the non-member operator is in another translation unit? An ODR violation? – Bo Persson Mar 21 '11 at 16:42
  • @GMan: So, how would you make a non-ODR-violating definition then? You always have to *define* it is *some* translation unit. – AnT stands with Russia Mar 21 '11 at 18:01
  • @GMan (first comment) The rule is applied to the class definition, when the definition is seen. C++ doesn't like the idea that a class can have two different definitions at different places in the same source file. – James Kanze Mar 21 '11 at 18:11
  • @Andrey @James: Sorry, I deleted my answer, forgot about the comments. I don't support any claims I made in this question any longer. :) Andrey answered it in another question, linked above. – GManNickG Mar 21 '11 at 18:44
  • "_What if the non-member operator is in another translation unit?_" Yes, what should happen according to you? "_An ODR violation?_" Why? Why would assignment mean the same thing in two TU? – curiousguy Dec 12 '11 at 01:27
2

Why is this?

Unless you declare one, the compiler declares an operator= in your class with signature operator= (C&, C&) or operator= (C&, const C&).

If you were allowed to overload assignment, most uses would be ambiguous.

Then you would likely lobby for additional rules to either:

  • pretend there is no compiler declared operator= if a user declared one is visible, as if the non-member operator= hides the member operator=
  • make your user declared assignment a better match during overloading.

Both choices would complicate rules that are already extremely complicated, adding a special case just for operator=.

Few people want to go there.

And also you haven't exposed a legitimate use for this feature.

Or, any reasonable use at all.

The C++ rules are only made even more complicated when some reasonable use-case can be showed.

curiousguy
  • 8,038
  • 2
  • 40
  • 58