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...