Namespaces
Variants

C++ named requirements: Swappable

From cppreference.net
C++ named requirements

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
using std:: swap ;
swap ( u, t ) ;

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
using std:: swap ;
swap ( t, u ) ;

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

1) Definieren Sie einen nicht-Member-swap im umschließenden Namespace, der an einen Member-swap weiterleiten kann, falls Zugriff auf nicht-öffentliche Datenelemente erforderlich ist.
2) Definieren Sie eine friend function innerhalb der Klasse (dieser Ansatz verbirgt die klassen-spezifische swap von der Namenssuche außer ADL).

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

prüft, ob Objekte eines Typs mit Objekten desselben oder eines anderen Typs ausgetauscht werden können
(Klassen-Template)
spezifiziert, dass ein Typ ausgetauscht werden kann oder dass zwei Typen miteinander ausgetauscht werden können
(Konzept)