2015-04-03 15 views
5

Der folgende Code ist, wie erwartet, nichtReturn "this" als rvalue

#include <iostream> 

class A 
{ 

    public: 

    A() = default; 
    ~A() = default; 

    A(const A&) = delete; 
    A(A&&) = delete; 

    A& operator=(const A&) = delete; 
    A& operator=(A&&) = delete; 

    A& operator<<(const int i) 
    { 
     std::cout << "operator<< called" << std::endl; 
     return *this; 
    } 

}; 

void foo(A&& a) 
{ 
    std::cout << "foo called" << std::endl; 
} 

int main() 
{ 
    A a; a << 14; 
    foo(std::move(a)); // works fine 

    foo(A() << 14); // does not compile 

    return 0; 
} 

Ändern der Klasse A bis

class A 
{ 

    public: 

    A() = default; 
    ~A() = default; 

    A(const A&) = delete; 
    A(A&&) = delete; 

    A& operator=(const A&) = delete; 
    A& operator=(A&&) = delete; 

    A& operator<<(const int i) & 
    { 
     std::cout << "operator<< called on lvalue" << std::endl; 
     return *this; 
    } 

    A&& operator<<(const int i) && 
    { 
     std::cout << "operator<< called on rvalue" << std::endl; 
     return std::move(*this); 
    } 


}; 

macht das Programm der Kompilierung kompilieren. Rückgabewerte rvalues ​​mit std :: move sind jedoch in der Regel keine gute Idee, da sie dangelnde Referenzen zurückgeben oder den Compiler daran hindern, bestimmte Optimierungen durchzuführen.

Ist der beschriebene Fall eine der wenigen Ausnahmen von der Faustregel "Rückgabe nicht mit Rvalue" oder sollte das Problem anders gelöst werden?

Vielen Dank!

+0

Ähnliche http://stackoverflow.com/questions/25334698/is-stdmovethis-a-good-pattern. – alfC

+0

Zum Vergleich, die Standard-Stream-Operatoren, die && Argumente nehmen sie als & zurück. http://en.cppreference.com/w/cpp/io/basic_ostream/operator_ltlt2 –

Antwort

0

Dieser Code ist absolut gültig und sicher. Als Ihr Objekt ist bereits ein R-Wert in

A&& operator<<(const int i) && 

es Gießen wieder rvalue (mit Bewegung) nicht die Sicherheit des Codes ändern. NRVO-Optimierung wird in diesem Fall nicht stattfinden, so dass die Geschwindigkeit des Codes wahrscheinlich nicht beeinträchtigt wird.

So wie Sie es formulieren würde ich sagen: „Ja, das ist eine Ausnahme von der Regel“

Auch diese Regel ist nicht universell: wenn Sie verstehen, was los ist (weshalb Sie diese Frage gestellt) Sie können sich auf Ihren gesunden Menschenverstand verlassen.