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!
Ähnliche http://stackoverflow.com/questions/25334698/is-stdmovethis-a-good-pattern. – alfC
Zum Vergleich, die Standard-Stream-Operatoren, die && Argumente nehmen sie als & zurück. http://en.cppreference.com/w/cpp/io/basic_ostream/operator_ltlt2 –