A() = A() - why does it compile?

C++

C++ Problem Overview


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

C++ Solutions


Solution 1 - C++

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.

Solution 2 - C++

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.

Solution 3 - C++

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionscdmbView Question on Stackoverflow
Solution 1 - C++Mike SeymourView Answer on Stackoverflow
Solution 2 - C++R. Martinho FernandesView Answer on Stackoverflow
Solution 3 - C++Praveen KumarView Answer on Stackoverflow