C++ named requirements: Swappable
Jeder Lvalue oder Rvalue dieses Typs kann mit jedem Lvalue oder Rvalue eines anderen Typs ausgetauscht werden, indem ein nicht qualifizierter Funktionsaufruf swap ( ) im Kontext verwendet wird, wo sowohl std::swap als auch die benutzerdefinierten swap ( ) s sichtbar sind.
Inhaltsverzeichnis |
Anforderungen
Typ U ist austauschbar mit Typ T, wenn für jedes Objekt u vom Typ U und jedes Objekt t vom Typ T,
| Ausdruck | Anforderungen | Semantik |
|---|---|---|
|
#include <algorithm> // until C++11
#include <utility> // since C++11
|
Nach dem Aufruf entspricht der Wert von
t
dem Wert, der vor dem Aufruf in
u
gespeichert war, und der Wert von
u
entspricht dem Wert, der vor dem Aufruf in
t
gespeichert war.
|
Ruft die Funktion namens swap ( ) auf, die durch Überladungsauflösung unter allen Funktionen mit diesem Namen gefunden wird, die durch argumentabhängige Suche und die beiden std::swap -Vorlagen im Header <algorithm> (bis C++11) <utility> (seit C++11) gefunden werden. |
|
#include <algorithm> // until C++11
#include <utility> // since C++11
|
Gleich | Gleich |
Viele Standardbibliotheksfunktionen (zum Beispiel viele Algorithmen) erwarten, dass ihre Argumente Swappable erfüllen, was bedeutet, dass immer wenn die Standardbibliothek einen Swap durchführt, sie das Äquivalent von using std:: swap ; swap ( t, u ) ; verwendet.
Typische Implementierungen führen entweder
Hinweise
Es ist nicht spezifiziert, ob <algorithm> (bis C++11) <utility> (seit C++11) tatsächlich eingebunden wird, wenn die Standardbibliotheksfunktionen den Swap durchführen, daher sollte die benutzerdefinierte swap ( ) nicht erwarten, dass sie eingebunden wird.
Beispiel
#include <iostream> #include <vector> struct IntVector { std::vector<int> v; IntVector& operator=(IntVector) = delete; // nicht zuweisbar void swap(IntVector& other) { v.swap(other.v); } void operator()(auto rem, auto term = " ") { std::cout << rem << "{{"; for (int n{}; int e : v) std::cout << (n++ ? ", " : "") << e; std::cout << "}}" << term; } }; void swap(IntVector& v1, IntVector& v2) { v1.swap(v2); } int main() { IntVector v1{{1, 1, 1, 1}}, v2{{2222, 2222}}; auto prn = [&]{ v1("v1", ", "), v2("v2", ";\n"); }; // std::swap(v1, v2); // Compilerfehler! std::swap erfordert MoveAssignable prn(); std::iter_swap(&v1, &v2); // OK: Bibliothek ruft unqualifiziertes swap() auf prn(); std::ranges::swap(v1, v2); // OK: Bibliothek ruft unqualifiziertes swap() auf prn(); }
Ausgabe:
v1{{1, 1, 1, 1}}, v2{{2222, 2222}};
v1{{2222, 2222}}, v2{{1, 1, 1, 1}};
v1{{1, 1, 1, 1}}, v2{{2222, 2222}};
Fehlerberichte
Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | Angewendet auf | Verhalten wie veröffentlicht | Korrigiertes Verhalten |
|---|---|---|---|
| LWG 226 | C++98 |
es war unklar, wie die Standardbibliothek
swap
verwendet
|
klargestellt zur Verwendung von sowohl
std::
als auch ADL-gefundenem
swap
|
Siehe auch
|
(C++17)
(C++17)
(C++17)
(C++17)
|
prüft, ob Objekte eines Typs mit Objekten desselben oder eines anderen Typs ausgetauscht werden können
(Klassen-Template) |
|
(C++20)
|
spezifiziert, dass ein Typ ausgetauscht werden kann oder dass zwei Typen miteinander ausgetauscht werden können
(Konzept) |