C++ named requirements: Swappable
Toute lvalue ou rvalue de ce type peut être échangée avec toute lvalue ou rvalue d'un autre type, en utilisant l'appel de fonction non qualifié swap ( ) dans le contexte où à la fois std::swap et les swap ( ) définis par l'utilisateur sont visibles.
Table des matières |
Exigences
Le type U est échangeable avec le type T si, pour tout objet u de type U et tout objet t de type T,
| Expression | Exigences | Sémantique |
|---|---|---|
|
#include <algorithm> // until C++11
#include <utility> // since C++11
|
Après l'appel, la valeur de
t
est la valeur détenue par
u
avant l'appel, et la valeur de
u
est la valeur détenue par
t
avant l'appel.
|
Appelle la fonction nommée swap ( ) trouvée par résolution de surcharge parmi toutes les fonctions de ce nom trouvées par recherche dépendante des arguments et les deux modèles std::swap définis dans l'en-tête <algorithm> (jusqu'à C++11) <utility> (depuis C++11) . |
|
#include <algorithm> // until C++11
#include <utility> // since C++11
|
Identique | Identique |
De nombreuses fonctions de la bibliothèque standard (par exemple, de nombreux algorithmes) attendent que leurs arguments satisfassent la condition Swappable , ce qui signifie qu'à chaque fois que la bibliothèque standard effectue un swap, elle utilise l'équivalent de using std:: swap ; swap ( t, u ) ; .
Les implémentations typiques soit
Notes
Il n'est pas spécifié si <algorithm> (jusqu'en C++11) <utility> (depuis C++11) est effectivement inclus lorsque les fonctions de la bibliothèque standard effectuent l'échange, donc la fonction swap ( ) fournie par l'utilisateur ne devrait pas s'attendre à ce qu'elle soit incluse.
Exemple
#include <iostream> #include <vector> struct IntVector { std::vector<int> v; IntVector& operator=(IntVector) = delete; // non 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); // Erreur de compilation ! std::swap nécessite MoveAssignable prn(); std::iter_swap(&v1, &v2); // OK : la bibliothèque appelle swap() non qualifié prn(); std::ranges::swap(v1, v2); // OK : la bibliothèque appelle swap() non qualifié prn(); }
Sortie :
v1{{1, 1, 1, 1}}, v2{{2222, 2222}};
v1{{2222, 2222}}, v2{{1, 1, 1, 1}};
v1{{1, 1, 1, 1}}, v2{{2222, 2222}};
Rapports de défauts
Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.
| DR | Applicable à | Comportement publié | Comportement corrigé |
|---|---|---|---|
| LWG 226 | C++98 |
il n'était pas clair comment la bibliothèque standard utilise
swap
|
clarifié pour utiliser à la fois
std::
et
swap
trouvé par ADL
|
Voir aussi
|
(C++17)
(C++17)
(C++17)
(C++17)
|
vérifie si les objets d'un type peuvent être échangés avec des objets du même type ou d'un type différent
(modèle de classe) |
|
(C++20)
|
spécifie qu'un type peut être échangé ou que deux types peuvent être échangés l'un avec l'autre
(concept) |