abraham_hilbert abraham_hilbert - 11 days ago 6
C++ Question

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.

Answer

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