A() = A() - why does it compile?
class A {};
int main() {
A() = A();
return 0;
}
Why does this code compile? Shouldn't be there some error that on the left side of assignment operator should be placed lvalue? Is A() lvalue? g++ 4.7 version
For built-in types, you'd be correct: the built-in assignment operator requires a modifiable lvalue on the left hand side.
However, this is not using the built-in operator, but the overload that's implicitly declared by the class. This is a member function, equivalent to
A().operator=(A());
and member functions can be called on rvalues.
If you really want, you can make it not compile with C++11:
class A {
template <typename T>
void operator=(T&&) && = delete; // no op= for rvalues
// generate other special members normally
A() = default;
A(A const&) = default;
A(A&&) = default;
~A() = default;
// op= only for lvalues
A& operator=(A&&) & = default;
A& operator=(A const&) & = default;
};
int main() {
A() = A(); // error
return 0;
}
(live example)
Note the &
and &&
(aka ref-qualifiers) at the end of the declarations of the various operator=
forms. This makes those declarations be selected for lvalues and rvalues respectively. However, the rvalue version, when selected by overload resolution causes the program to be ill-formed because it is deleted.
The default generated operator=, however, does not have any ref-qualifier, meaning it can be called for both lvalues and rvalues; that's why the code in the question compiles, even though A()
is an rvalue.
C++ compiler provides all classes with a default constructor, that's what happening, with respect to your code, when you say A()=A(); it just invokes the constructor with a nameless object and the function returns reference to the constructed object (implicit). That's it...