6

In the following example:

class A {
  private: double content;

  public:
  A():content(0) {}

  A operator+(const A& other) {     
    content += other.content;
    return *this;
  }

 void operator=(const A& other) {
       content = other.content;
  }

};

A is a simple wrapper for a double for which the + and = operators have been overloaded. In the following use:

 int main(int argc, char *argv[]) {
    A a, b, c;
    (a+b) = c ; // Why is this operation legal?
}

Why does (a+b) = c compile? I would like to know why this statement is legal, because the result of (a+b) must be an rvalue. I am not returning a reference from operator+.

Fantastic Mr Fox
  • 32,495
  • 27
  • 95
  • 175
ForeverStudent
  • 2,487
  • 1
  • 14
  • 33
  • 2
    Overloaded operators are just function calls; they don't enjoy any special restrictions on the value categories of their arguments. Since you didn't ref-qualify the assignment operator overload, it accepts instances of any value category. – Kerrek SB Nov 18 '15 at 15:30
  • can you please elaborate – ForeverStudent Nov 18 '15 at 15:33
  • 1
    Well, you aren't complaining that `(a + b).display()` works, right? – Kerrek SB Nov 18 '15 at 15:36

1 Answers1

14

(a+b) = c is the same as (a+b).operator=(c). There is no special rule for rvalue references in assignment operators, it just follows usual function call rules. If you want to prevent calling with rvalues, you can add a ref-qualifier:

void operator= (const A& other) & {
//                              ^
     content = other.content;
}

This will only allow the function to be called on lvalues.

TartanLlama
  • 63,752
  • 13
  • 157
  • 193
  • so, normally = as the default assignment operator requires an lvalue on the left hand side ( apart from C++11 rvalue references), but when I overload = myself then that requirement goes out the window, right? – ForeverStudent Nov 18 '15 at 15:45
  • @IIIIIIIIIIIIIIIIIIIIIIII yes. – TartanLlama Nov 18 '15 at 15:56
  • 1
    @TartanLlama No actually; the default `operator=` for a class type also allows a prvalue on the left-hand side. It doesn't make a difference whether there is a user-provided overload. You're obviously referring to having a primitive type on the left (not sure if OP was also clear on that) – M.M Sep 25 '18 at 04:54