Namensräume
Varianten
Aktionen

C++ benannte Anforderungen: Swappable

Von cppreference.com
 
 
C++ benannte Anforderungen
 

Jeder Lvalue oder Rvalue dieses Typs kann mit jedem Lvalue oder Rvalue eines anderen Typs vertauscht werden, unter Verwendung eines unqualifizierten Funktionsaufrufs swap() im Kontext, in dem sowohl std::swap als auch der benutzerdefinierte swap() sichtbar sind.

Inhalt

[bearbeiten] Anforderungen

Typ U ist mit Typ T vertauschbar, wenn für jedes Objekt u vom Typ U und jedes Objekt t vom Typ T gilt:

Ausdruck Anforderungen Semantik
#include <algorithm> // bis C++11

#include <utility> // seit C++11
using std::swap;
swap(u, t);

Nach dem Aufruf ist der Wert von t der Wert, den u vor dem Aufruf enthielt, und der Wert von u ist der Wert, den t vor dem Aufruf enthielt. Ruft die Funktion mit dem Namen swap() auf, die durch Überladungsauflösung unter allen Funktionen mit diesem Namen gefunden wird, die durch argumentabhängige Suche gefunden werden, sowie die beiden std::swap-Vorlagen, die in der Header-Datei <algorithm>(bis C++11)<utility>(seit C++11) definiert sind.
#include <algorithm> // bis C++11

#include <utility> // seit C++11
using std::swap;
swap(t, u);

Dasselbe Dasselbe

Viele Funktionen der Standardbibliothek (z. B. viele Algorithmen) erwarten, dass ihre Argumente Swappable erfüllen, was bedeutet, dass die Standardbibliothek immer dann, wenn sie einen Tausch durchführt, das Äquivalent von using std::swap; swap(t, u); verwendet.

Typische Implementierungen definieren entweder

1) Eine nicht-member-Funktion swap im umgebenden Namensraum, die auf eine member-Funktion swap weiterleiten kann, falls Zugriff auf nicht-öffentliche Datenmember erforderlich ist.
2) Eine friend-Funktion in der Klasse (dieser Ansatz verbirgt die klassenspezifische swap vor der Namenssuche, außer der ADL).

[bearbeiten] Anmerkungen

Es ist nicht spezifiziert, ob <algorithm>(bis C++11)<utility>(seit C++11) tatsächlich eingebunden wird, wenn die Funktionen der Standardbibliothek den Tausch durchführen. Daher sollte die vom Benutzer bereitgestellte swap() nicht davon ausgehen, dass sie eingebunden ist.

[bearbeiten] Beispiel

#include <iostream>
#include <vector>
 
struct IntVector
{
    std::vector<int> v;
 
    IntVector& operator=(IntVector) = delete; // not assignable
 
    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); // Compiler error! std::swap requires MoveAssignable
    prn();
    std::iter_swap(&v1, &v2); // OK: library calls unqualified swap()
    prn();
    std::ranges::swap(v1, v2); // OK: library calls unqualified swap()
    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}};

[bearbeiten] 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 klarstellung, dass sowohl std:: als auch ADL-gefundene swap verwendet werden

[bearbeiten] Siehe auch

prüft, ob Objekte eines Typs mit Objekten desselben oder eines anderen Typs vertauscht werden können
(Klassenvorlage) [bearbeiten]
gibt an, dass ein Typ vertauscht werden kann oder dass zwei Typen miteinander vertauscht werden können
(Konzept) [bearbeiten]