Heim > Backend-Entwicklung > C++ > Wie bindet std::move() an L-Werte, wenn R-Wert-Referenzen nur an R-Werte binden sollen?

Wie bindet std::move() an L-Werte, wenn R-Wert-Referenzen nur an R-Werte binden sollen?

DDD
Freigeben: 2024-11-14 10:46:01
Original
1034 Leute haben es durchsucht

How does std::move() bind to lvalues when rvalue references are supposed to only bind to rvalues?

Das Geheimnis der Konvertierungsmagie von std::move lüften

Beim Aufruf von std::move() ist es rätselhaft zu beobachten, dass die referenzierte Der R-Wert-Parameter kann an L-Werte gebunden werden, die normalerweise nicht an R-Wert-Referenzen angehängt werden dürfen. Wenn man sich mit der Implementierung von std::move() befasst, offenbart sich der Schlüssel zu diesem scheinbaren Paradoxon.

Analyse der std::move()-Implementierung

Beginnend mit dem Verfeinerten Version von std::move():

template <typename T>
typename remove_reference<T>::type&& move(T&& arg) {
  return static_cast<typename remove_reference<T>::type&&>(arg);
}
Nach dem Login kopieren

Fall 1: Aufruf von move() mit R-Werten

Wenn move() mit R-Werten verwendet wird, z ein temporäres Objekt:

Object a = std::move(Object()); // Object() is temporary, hence prvalue
Nach dem Login kopieren

Die resultierende Vorlageninstanziierung ist:

remove_reference<Object>::type&& move(Object&& arg) {
  return static_cast<remove_reference<Object>::type&&>(arg);
}
Nach dem Login kopieren

Da „remove_reference“ T& in T oder T&& in T umwandelt und Object ein einfacher Wert ist, ist die endgültige Funktionsmorphologie wird zu:

Object&& move(Object&& arg) {
  return static_cast<Object&&>(arg);
}
Nach dem Login kopieren

Die Besetzung ist entscheidend, da benannte R-Wert-Referenzen als L-Werte behandelt werden.

Fall 2: Aufruf von move() mit L-Werten

Wenn move() mit L-Werten aufgerufen wird:

Object a; // a is an lvalue
Object b = std::move(a);
Nach dem Login kopieren

Die resultierende move()-Instanziierung lautet:

remove_reference<Object&>::type&& move(Object& && arg) {
  return static_cast<remove_reference<Object&>::type&&>(arg);
}
Nach dem Login kopieren

Auch hier übersetzt „remove_reference“ Object& in Object und ergibt:

Object&& move(Object& && arg) {
  return static_cast<Object&&>(arg);
}
Nach dem Login kopieren

Die Essenz des Referenzkollaps

Das Verständnis von Objekt& && und seiner Fähigkeit, sich an L-Werte zu binden, ist der Schlüssel zur Lösung des Rätsels. C 11 führt spezielle Regeln für das Reduzieren von Referenzen ein, die Folgendes vorschreiben:

Object & && = Object &
Object & &&& = Object &
Object && & = Object &
Object && &&& = Object &&
Nach dem Login kopieren

Somit wird Object& && tatsächlich in Object& übersetzt, eine typische L-Wert-Referenz, die sich mühelos an L-Werte bindet.

Die Resultierende Funktion

Mit diesen Regeln wird die endgültige Funktion zu:

Object&& move(Object& arg) {
  return static_cast<Object&&>(arg);
}
Nach dem Login kopieren

Sie spiegelt die Instanziierung für R-Werte wider und wandelt ihr Argument in eine R-Wert-Referenz um, wodurch ein einheitliches Verhalten sichergestellt wird .

Die Bedeutung von „remove_reference“

Der Zweck von „remove_reference“ wird deutlich, wenn man eine alternative Funktion untersucht:

template <typename T>
T&& wanna_be_move(T&& arg) {
  return static_cast<T&&>(arg);
}
Nach dem Login kopieren

Bei Instanziierung mit einem L-Wert:

Object& && wanna_be_move(Object& && arg) {
  return static_cast<Object& &&&>(arg);
}
Nach dem Login kopieren

Das Anwenden von Regeln zum Reduzieren von Referenzen zeigt eine unbrauchbare verschiebungsähnliche Funktion, die L-Werte für L-Wert-Argumente zurückgibt. Der Übeltäter ist das Fehlen von „remove_reference“, was die ordnungsgemäße Konvertierung in R-Wert-Referenzen behindert.

Das obige ist der detaillierte Inhalt vonWie bindet std::move() an L-Werte, wenn R-Wert-Referenzen nur an R-Werte binden sollen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage