2

Why is the following code correct:

struct A
{
  A operator+( A const& elem )
  {
    return *this;
  }

  bool operator==( A const& elem )
  {
    return true;
  }

  operator bool()
  {
    return true;
  }
};


int main()
{
  A a_1, a_2;

  if( ((a_1+a_2) = a_1) )
  {}
}

Here, I expected an error in the if-statement since a_1 + a_2 is an r-value. Replacing the line A a_1, a_2; by int a_1, a_2; leads to the expected error:

error: expression is not assignable
      if( ((a_1+a_2) = a_1) )
           ~~~~~~~~~ ^
1 error generated.
abraham_hilbert
  • 2,221
  • 1
  • 13
  • 30

1 Answers1

1

Because for the class A, (a_1+a_2) = a_1 will be just parsed as a call to A::operator=(const A&) at last. Even what a_1+a_2 returns is a temporary object, call the member function on it is still valid.

If you want to prohibit such calls on temporary objects, you might use ref-qualified member functions (since C++11), which could be used for distinguishing the objects called on are l-values or r-values. e.g.

struct A
{
  //...
  A& operator=(const A&) && = delete; // prevent from calling with temporary objects
  A& operator=(const A&) & = default;
};
songyuanyao
  • 169,198
  • 16
  • 310
  • 405