C++ named requirements: Swappable
Any lvalue or rvalue of this type can be swapped with any lvalue or rvalue of some other type, using unqualified function call swap() in the context where both std::swap and the user-defined swap()s are visible.
Требования
Тип U является совместимым с типом T, если для любого объекта u типа U и любого объекта t типа T,
| Выражение | Требования | Семантика |
|---|---|---|
#include <algorithm> // until C++11 | После вызова значение t равно значению, содержавшемуся в u до вызова, а значение u равно значению, содержавшемуся в t до вызова. | Вызывает функцию с именем swap(), найденную по резолюции перегрузки среди всех функций с этим именем, которые найдены с помощью поиска с учетом аргументов и двух шаблонов std::swap, определенных в заголовке <algorithm>(до C++11)<utility>(с C++11). |
#include <algorithm> // until C++11 | То же самое | То же самое |
Многие стандартные библиотечные функции (например, многие алгоритмы) ожидают, что их аргументы удовлетворяют условию Swappable, что означает, что каждый раз, когда стандартная библиотека выполняет операцию swap, она использует эквивалент using std::swap; swap(t, u);.
Типичные реализации либо
Примечания
Не определено, включен ли <algorithm>(до C++11)<utility>(с C++11) в действительности при выполнении операций swap стандартными библиотечными функциями, поэтому пользовательская swap() не должна ожидать его включения.
Пример
#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();
}Вывод:
v1{{1, 1, 1, 1}}, v2{{2222, 2222}};
v1{{2222, 2222}}, v2{{1, 1, 1, 1}};
v1{{1, 1, 1, 1}}, v2{{2222, 2222}};Отчеты об ошибках
Следующие отчеты об ошибках, меняющие поведение, были применены ретроактивно к ранее опубликованным стандартам C++.
| DR | Применен к | Поведение как опубликовано | Корректное поведение |
|---|---|---|---|
| LWG 226 | C++98 | было неясно, как стандартная библиотека использует swap | уточнено, что используется и std::, и найденная ADL swap |
См. также
|
(C++17)(C++17)(C++17)(C++17) | проверяет, могут ли объекты типа быть поменяв местами с объектами того же или другого типа (шаблон класса) |
|
(C++20) | определяет, что тип может быть поменяв местами или что два типа могут быть поменяв местами друг с другом (концепция) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/named_req/Swappable