Requisitos denominados de C++: Swappable
Cualquier lvalue o rvalue de este tipo puede intercambiarse con cualquier lvalue o rvalue de algún otro tipo, usando una llamada a la función swap() no calificada en el contexto donde tanto std::swap como los swap()s definidos por el usuario son visibles.
Requisitos
Un tipo U es intercambiable con un tipo T si, para cualquier objeto u de tipo U y cualquier objeto t de tipo T,
| Expresión | Requisitos | Semántica |
|---|---|---|
#include <algorithm> // hasta C++11 #include <utility> // desde C++11 using std::swap; swap(u, t);
|
Después de la llamada, el valor de t es el valor mantenido por u antes de la llamada, y el valor de u es el valor mantenido por t antes de la llamada.
|
Llama a la función denominada swap() encontrada mediante la resolución de sobrecarga entre todas las funciones con ese nombre que se encuentran mediante la búsqueda dependiente de argumento y las dos plantillas std::swap definidas en el archivo de encabezado <algorithm> (hasta C++11)<utility> (desde C++11).
|
#include <algorithm> // hasta C++11 #include <utility> // desde C++11 using std::swap; swap(t, u);
|
Los mismos | La misma |
Varias funciones de la biblioteca estándar (por ejemplo, varios algoritmos) esperan que sus argumentos satisfagan a Swappable, lo que significa que en cualquier ocasión en que la biblioteca estándar realiza un intercambio, utiliza el equivalente a usar using std::swap; swap(t, u);.
Implementaciones típicas
swap en el espacio de nombres circundante, que puede redirigirse a una función miembro swap si se requiere acceder a miembros de datos que no son públicos.swap específica de la clase de una búsqueda de nombre distinta de la búsqueda dependiente de argumento).Notas
No está especificado si <algorithm> (hasta C++11)<utility> (desde C++11) se incluye realemente cuando las funciones de la biblioteca estándar realizan el intercambio, de tal manera que la función swap() proporcionada por el usuario no debe esperar que se incluya.
Ejemplo
#include <iostream>
#include <vector>
struct IntVector
{
std::vector<int> v;
IntVector& operator=(IntVector) = delete; // no es asignable
void swap(IntVector& otro)
{
v.swap(otro.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 de compilación. std::swap requiere MoveAssignable
prn();
std::iter_swap(&v1, &v2); // Correcto: la biblioteca llama a swap() sin calificar
prn();
std::ranges::swap(v1, v2); // Correcto: la biblioteca llama a swap() sin calificar
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 de cambio de comportamiento se aplicaron de manera retroactiva a los estándares de C++ publicados anteriormente.
| ID | Aplicado a | Comportamiento según lo publicado | Comportamiento correcto |
|---|---|---|---|
| LWG 226 | C++98 | no estaba claro cómo la biblioteca estándar utiliza swap
|
Se aclaró el uso tanto de std:: como la búsqueda ADL de swap
|
Véase también
(C++17)(C++17)(C++17)(C++17) |
Comprueba si objetos de un tipo pueden intercambiarse con objetos del mismo tipo o diferente tipo. (plantilla de clase) |
(C++20) |
especifica que un tipo se puede intercambiar o que dos tipos se pueden intercambiar entre sí (concepto) |