Warum ist "std::move` mit dem Namen `std::move"?
C++11 std::move(x)
Funktion nicht wirklich nach überhaupt nichts. Es ist nur eine Besetzung an den r-Wert. Warum wurde das gemacht? Ist das nicht irreführend?
Erschwerend kommt hinzu, dass die drei-argument
Und vergessen Sie nicht über die C++98/03/11
Mein anderer Favorit ist
Ich fände
std::move
tatsächlich bewegt..Und vergessen Sie nicht über die C++98/03/11
std::char_traits::move
🙂Mein anderer Favorit ist
std::remove()
was nicht, entfernen Sie die Elemente: Sie haben noch zu nennen erase()
tatsächlich entfernen Sie diese Elemente aus dem container. So move
bewegt sich nicht, remove
nicht entfernen. Ich würde aufgepickt haben Namen mark_movable()
für move
.Ich fände
mark_movable()
verwirrend auch. Es schlägt einen bleibenden Nebenwirkung, wo es tatsächlich keine gibt.InformationsquelleAutor Howard Hinnant | 2014-01-26
Du musst angemeldet sein, um einen Kommentar abzugeben.
Es ist richtig, dass
std::move(x)
ist nur ein cast auf rvalue - genauer gesagt zu einer xvalue, im Gegensatz zu einer prvalue. Und es ist auch wahr, dass ein Darsteller namensmove
Leute manchmal verwirrt. Aber der Sinn dieser Benennung ist nicht zu verwechseln, aber eher, um Ihren code lesbarer zu gestalten.Die Geschichte der
move
stammt die ursprüngliche bewegen Vorschlag 2002. Dieses Papier stellt zunächst die rvalue-Referenz und zeigt dann, wie zu schreiben, ein effizienterstd::swap
:Muss man daran erinnern, dass an diesem Punkt in der Geschichte, das einzige, was "
&&
" könnte möglicherweise bedeuten, war logische und. Niemand war vertraut mit rvalue-Referenzen, noch die Auswirkungen von casting-ein lvalue auf einen rvalue (die zwar nicht, eine Kopie alsstatic_cast<T>(t)
tun würde). Damit die Leser dieser code würde natürlich denken:Beachten Sie auch, dass
swap
ist eigentlich nur ein stand-in für alle Arten von permutations-algorithmen ändern. Diese Diskussion ist viel, viel größer alsswap
.Dann der Vorschlag syntax-Zucker ersetzt
static_cast<T&&>
mit etwas mehr lesbar vermittelt nicht das genaue was, sondern die warum:I. e.
move
ist nur syntax sugar fürstatic_cast<T&&>
, und nun der code ist ziemlich suggestiv, warum diese Modelle gibt es: damit die move-Semantik!Muss man verstehen, dass im Kontext von Geschichte, die nur wenige Menschen zu diesem Zeitpunkt wirklich verstanden, die intime Verbindung zwischen rvalues und move-Semantik (obwohl das Papier versucht zu erklären, dass, wie auch):
Wenn zu der Zeit
swap
war stattdessen stellte wie diese:Dann müssten die Leute angeschaut und gesagt:
Der wichtigste Punkt:
Wie es war, mit
move
, niemand hat jemals gefragt:Als die Jahre ging auf und der Vorschlag wurde verfeinert, die Vorstellungen von lvalue und rvalue wurde verfeinert, in die Wert Kategorien, die wir heute haben:
(Bild schamlos geklaut von dirkgently)
Und so auch heute, wenn wir wollten
swap
genau sagen was es tut, anstatt warum, es sollte Aussehen wie:Und die Frage sollte jeder sich Fragen wird, wenn der obige code ist mehr oder weniger lesbar als:
Oder sogar das original:
In jedem Fall, der Geselle C++ - Programmierer sollten wissen, dass unter der Haube von
move
nichts mehr Los ist, als eine Besetzung. Für Anfänger in C++ - Programmierer, zumindest mitmove
werden darüber informiert, dass das Absicht ist, um bewegen aus der RS, im Gegensatz zu kopieren von RS, auch wenn Sie nicht genau verstehen wie das erreicht ist.Zusätzlich, wenn ein Programmierer dies wünscht Funktionalität unter einem anderen Namen,
std::move
besitzt kein Monopol auf diese Funktionalität, und es gibt keine nicht-portable Sprache mit Magie zu tun in der Umsetzung. Zum Beispiel, wenn man wollte, um codeset_value_category_to_xvalue
, und verwenden Sie stattdessen, ist es trivial zu tun:In C++14 wird es sogar noch präziser:
Also, wenn Sie so geneigt sind, schmücken Sie Ihre
static_cast<T&&>
aber Sie denken am besten, und vielleicht werden Sie am Ende der Entwicklung eine neue best-practice-C++ wird ständig weiterentwickelt).So was tut
move
tun in Bezug auf erzeugte Objekt-code?Betrachten Sie diese
test
:Zusammengestellt
clang++ -std=c++14 test.cpp -O3 -S
ergibt sich dieses Objekt code:Nun, wenn der test geändert:
Es ist absolut überhaupt keine Veränderung im Objekt-code. Man kann verallgemeinern das Ergebnis: Für trivial beweglichen Objekte
std::move
hat keine Auswirkungen.Betrachten wir nun das Beispiel:
Diesem generiert:
Wenn Sie
__ZN1XaSERKS_
durchc++filt
es produziert:X::operator=(X const&)
. Keine überraschung hier. Nun, wenn der test geändert:Dann gibt es noch keinerlei Veränderung in die generierte Objekt-code.
std::move
hat nichts getan, aber gewirktj
zu einem rvalue, und dann, dass rvalueX
bindet an die copy-Zuweisungsoperator vonX
.Nun fügen Sie einen move-Zuweisungs-operator zu
X
:Nun den Objekt-code hat ändern:
Läuft
__ZN1XaSEOS_
durchc++filt
zeigt, dassX::operator=(X&&)
genannt wird, stattX::operator=(X const&)
.Und das ist alles dort ist zu
std::move
! Es verschwindet vollständig bei der Laufzeit. Ihre einzige Auswirkung ist zur compile-Zeit, wo es könnte verändern, was überladung aufgerufen wird.digraph D { glvalue -> { lvalue; xvalue } rvalue -> { xvalue; prvalue } expression -> { glvalue; rvalue } }
für das öffentliche gut 🙂 Laden Sie es hier als SVGIst diese noch offen, bikeshedding? Ich würde vorschlagen
allow_move
😉oder
please_move
odermark_as_movable
.Scott Meyers vorgeschlagene Umbenennung
std::move
zurvalue_cast
: youtube.com/...Da rvalue bezieht sich jetzt auf beide prvalues und xvalues,
rvalue_cast
ist vieldeutig, in seiner Bedeutung: welche Art von rvalue tut es wieder?xvalue_cast
wäre eine konsistente Namen hier. Leider sind die meisten Menschen zu dieser Zeit, würde auch nicht verstehen, was es tut. In ein paar Jahren, meine Aussage wird sich hoffentlich falsch.InformationsquelleAutor Howard Hinnant
Lassen Sie mich nur verlassen, hier ein Zitat aus der C++11-FAQ geschrieben von B. Stroustrup, die eine direkte Antwort auf Ops Frage:
Durch die Art und Weise, ich wirklich genossen die FAQ - es lohnt sich zu Lesen.
InformationsquelleAutor podkova