class MyClass {
public:
MyClass()
{
std::cout << "default constructor\n";
}
MyClass(MyClass& a)
{
std::cout << "copy constructor\n";
}
MyClass(MyClass&& b)
{
std::cout << "move constructor\n";
}
};
void test(MyClass&& temp)
{
MyClass a(MyClass{}); // calls MOVE constructor as expected
MyClass b(temp); // calls COPY constructor... not expected...?
}
int main()
{
test(MyClass{});
return 0;
}
Für den obigen Code, erwartete ich beide Objekt Schöpfungen in Test() bewegen Konstruktor zu nennen, weil a b rvalue Referenztyp (MyClass & &) ist.C++ Konstruktor bewegen sich nicht für rvalue Referenz genannt
Die Übergabe von b an den MyClasss- Konstruktor ruft den move -Konstruktor jedoch nicht wie erwartet auf, sondern ruft stattdessen den Kopierkonstruktor auf.
Warum ruft der zweite Fall den Kopierkonstruktor auf, auch wenn das übergebene Argument vom Typ MyClass ist & & (r-Wert-Referenz) ???
Ich benutze gcc 5.2.1. Um meine Ergebnisse zu reproduzieren, müssen Sie die Option -fno-elide-constructors an gcc übergeben, um die Kopieroptimierung zu deaktivieren.
void test(MyClass&& temp)
{
if (std::is_rvalue_reference<decltype(temp)>::value)
std::cout << "temp is rvalue reference!!\n";
else
std::cout << "temp is NOT rvalue!!\n";
}
Above Code druckt "temp rvalue Referenz", auch wenn Temp gestattet.
Temp-Typ ist R-Wert Referenztyp.
Ausdruck 'temp' zu einem L-Wert refernce auswertet, keine rvalue Referenz. Die Tatsache, dass Sie 'temp' als rvalue-Referenz deklariert haben, spielt keine Rolle. Eine * benannte * Referenz ist immer ein L-Wert. – AnT
@AnT Haben Sie Referenzen in C++ - Standarddokumenten? Ich habe mich sehr bemüht, nach einem Hinweis auf diese Regel zu suchen, aber ich konnte keinen finden ... – SHH
Siehe den Anfang von ** 5 Ausdrücke **. Es ist alles in 5/5, 5/6 und 5/7. Vgl. Insbesondere Note 5/7, die im Grunde genau das angibt. Auch das verlinkte "Duplikat" hat einen Link zu einem Artikel von Thomas Becker zum Thema. – AnT