C++ named requirements: Swappable
Cualquier lvalue o rvalue de este tipo puede intercambiarse con cualquier lvalue o rvalue de algún otro tipo, usando la llamada de función no calificada swap ( ) en el contexto donde tanto std::swap como las funciones swap ( ) definidas por el usuario son visibles.
Contenidos |
Requisitos
El tipo U es intercambiable con el tipo T si, para cualquier objeto u de tipo U y cualquier objeto t de tipo T,
| Expresión | Requisitos | Semántica |
|---|---|---|
|
#include <algorithm> // until C++11
#include <utility> // since C++11
|
Después de la llamada, el valor de
t
es el valor contenido en
u
antes de la llamada, y el valor de
u
es el valor contenido en
t
antes de la llamada.
|
Llama a la función llamada swap ( ) encontrada mediante resolución de sobrecarga entre todas las funciones con ese nombre que se encuentran mediante búsqueda dependiente de argumento y las dos plantillas std::swap definidas en el encabezado <algorithm> (until C++11) <utility> (since C++11) . |
|
#include <algorithm> // until C++11
#include <utility> // since C++11
|
Igual | Igual |
Muchas funciones de la biblioteca estándar (por ejemplo, muchos algoritmos) esperan que sus argumentos satisfagan Swappable , lo que significa que cada vez que la biblioteca estándar realiza un swap, utiliza el equivalente de using std:: swap ; swap ( t, u ) ; .
Las implementaciones típicas o bien
Notas
No está especificado si <algorithm> (until C++11) <utility> (since C++11) es realmente incluido cuando las funciones de la biblioteca estándar realizan el swap, por lo que el swap ( ) proporcionado por el usuario no debería esperar que esté incluido.
Ejemplo
#include <iostream> #include <vector> struct IntVector { std::vector<int> v; IntVector& operator=(IntVector) = delete; // no asignable 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); // ¡Error del compilador! std::swap requiere MoveAssignable prn(); std::iter_swap(&v1, &v2); // OK: la biblioteca llama a swap() no calificada prn(); std::ranges::swap(v1, v2); // OK: la biblioteca llama a swap() no calificada prn(); }
Salida:
v1{{1, 1, 1, 1}}, v2{{2222, 2222}};
v1{{2222, 2222}}, v2{{1, 1, 1, 1}};
v1{{1, 1, 1, 1}}, v2{{2222, 2222}};
Informes de defectos
Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares publicados anteriormente de C++.
| DR | Aplicado a | Comportamiento publicado | Comportamiento correcto |
|---|---|---|---|
| LWG 226 | C++98 |
no estaba claro cómo la biblioteca estándar utiliza
swap
|
aclarado para usar tanto
std::
como
swap
encontrado por ADL
|
Véase también
|
(C++17)
(C++17)
(C++17)
(C++17)
|
verifica si objetos de un tipo pueden intercambiarse con objetos del mismo tipo o de diferente tipo
(plantilla de clase) |
|
(C++20)
|
especifica que un tipo puede intercambiarse o que dos tipos pueden intercambiarse entre sí
(concepto) |