Könnte std::deque::pop_front in C++0x value_type&& zurückgeben?
-
Hi,
std::deque::pop_frontgibt javoidzurück, aus nachvollziehbaren Gründen.Mit C++0x gibt's aber ja RValue-Referenzen, müsste es dann nicht klappen, dass
pop_fronteinfachT&&zurückgibt, das erste Element halt? Ich stelle mir das etwa so vor:class deque { ... value_type&& pop_front() { value_type Object = move( front() ); erase( begin() ); return Object; } };So dürfte doch in keinem Fall ein Kopierkonstruktor aufgerufen werden, oder irre ich mich? Nur der Destruktor falls das Objekt übernommen wird, den Destruktor kann man in der void-Version aber sowieso nicht vermeiden.
Oder hab ich was übersehen?
-
Was ist, wenn
Tnicht movable ist? Würde dann nicht eine Kopie erstellt?
-
Nexus schrieb:
Was ist, wenn
Tnicht movable ist? Würde dann nicht eine Kopie erstellt?Oha, da ist der Haken. Danke!
-
Er.
Mag sein dass ich da was verpennt habe bezüglich Rvalue-Referenzen... aber: seit wann ist es OK eine Referenz (Rvalue oder nicht) auf eine lokale Variable zurückzuliefern?
-
Er.
Mag sein dass ich da was verpennt habe bezüglich Rvalue-Referenzen... aber: seit wann ist es OK eine Referenz (Rvalue oder nicht) auf eine lokale Variable zurückzuliefern?
Ich habe diesbezüglich vor kurzem ein interessantes Video auf Channel 9 mit "Mister S.T.L" gesehen(Link füge ich später noch hinzu). Offenbar unterlief selbst dem Standardkomitee in einem der Proposals genau derselbe Fehler. Und nein, man sollte keine (RValue-)Referenzen auf lokale Variablen zurückgeben... Niemals!

Edit: So hier der Link
http://channel9.msdn.com/Shows/Going+Deep/C9-Lectures-Stephan-T-Lavavej-Standard-Template-Library-STL-9-of-n
Ab Minute 31 wird auf das Problem eingegangen.
Im übrigen kann ich diese Videolektüre(10 Stück sind es an der Zahl) nur jedem empfehlen, der sich mit der STL auseinandersetzen will/muss.
-
Stimmt, da hat mich krümelkacker letztes Mal drauf hingewiesen. Richtig wäre glaube ich
value_type pop_front();und der Move-Konstruktor wird falls vorhanden automatisch aufgerufen.
Wenn du ein
pop_front()willst, das das Element zurückgibt (und für movable Typen exceptionsicher ist), sollte das eigentlich als freie Funktion machbar sein.
-
@Matzer: Danke für den Link. Sehe mir das gerade an (bzw. versuche es, viel mehr als "buffering" kommt da gerade nicht
).Matzer schrieb:
"Mister S.T.L"
Das ist für mich immer noch P.J.Plauger, obwohl bei ihm die Initialen nicht passen

-
Mal ne Blöde Frage bezüglich den Rvalue references:
Angenommen std::string hat einen Move-Ctor:
struct fooyou { int bar1; std::string bar2; fooyou() : bar1(0), bar2() { } fooyou(int bar) : bar1(bar), bar2("bar entered") { } }; fooyou test = fooyou(123);Wird hier der String kopiert oder verschoben?
-
Wir wissen doch alle, dass das für STephanov&Lee steht.

-
Ethon schrieb:
Angenommen std::string hat einen Move-Ctor:
struct fooyou { int bar1; std::string bar2; fooyou() : bar1(0), bar2() { } fooyou(int bar) : bar1(bar), bar2("bar entered") { } }; fooyou test = fooyou(123);Wird hier der String kopiert oder verschoben?
Wo genau ist "hier"? Ich nehme an, Du meinst damit die letzte Zeile mit der Kopierinitialisierung. Nun, weil auf der rechten Seite ein Rvalue-Ausdruck steht, darf der Compiler versuchen, die "Kopie" komplett wegzuoptimieren. Das heißt, ein gescheiter Compiler wird mit oder ohne Rvalue-Referenzen nur ein einziges Objekt vom Typ fooyou erzeugen, ohne dass irgendwas kopiert werden muss. Erwähnenswerte Änderungen in C++0x sind:
- Überall dort, wo der C++03 Standard dem Compiler das Wegoptimieren von Kopien explizit erlaubt ("copy elision", siehe 12.8/15 [class.copy]) es aber aber aus irgendwelchen Gründen nicht tun kann, zwingt der kommende C++ Standard den Compiler, einen Move-Konstruktor zu benutzen (falls vorhanden).
- Falls der Benutzer keinen Dtor, Copy-Ctor oder Copy-Assignment einer Klasse deklariert und falls die Datenelemente einer Klasse "move-bar" sind, erzeugt der Compiler entsprechende Move-Operationen automatisch.
In diesem konkreten Fall ist fooyou aufgrund der vom Compiler erzeugbaren Move-Operationen move-konstruierbar und move-zuweisbar. Also, entweder wird der Compiler direkt nur ein fooyou-Objekt erzeugen (falls er die "copy elision" durchführen kann) oder er wird seinen implizit generierten Move-Ctor für fooyou bemühen, welcher alle Datenelemente "movt". Es wird hier also garantiert kein String-Objekt kopiert.