Frage

struct A {};

A f1()
{
    return A();
}

int f2()
{
    return int();
}

int main()
{
    f1() = A();   // OK
    f2() = int(); // error C2106: '=' : left operand must be l-value
}

Why is f1() = A(); OK while f2() = int(); is failed?

War es hilfreich?

Lösung 2

The function f1 returns a rvalue, which might become an xvalue (an “eXpiring” value). The function f2 returns a builtin type which is an rvalue becomming an prvalue (“pure” rvalue).

From 3.10 [Lvalues and rvalues]

— An xvalue (an “eXpiring” value) also refers to an object, usually near the end of its lifetime (so that its resources may be moved, for example). An xvalue is the result of certain kinds of expressions involving rvalue references (8.3.2).

Hence, due to an implicit move operation the assignment of A becomes valid.

Changing A to:

struct A {
    A() {}
    A(A&&) = delete;
    A& operator = (const A&) { return *this; }
};

produces: error: use of deleted function ‘A::A(A&&)’ with g++ (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2

Andere Tipps

f1() returns an instance of A. Since you haven't overwritten the copy/move-assignment operator, the compiler generates one for you. You're essentially calling a member function:

f1() = A(); // calls A& operator=(A&&)

The second doesn't work because int is not of class type.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top