Q:

Assignable r-value

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.

A:

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;
};

