|
|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Any lvalue or rvalue of this type can be swapped with any lvalue or rvalue of some other type, using unqualified function callswap() in the context where bothstd::swap and the user-definedswap()s are visible.
Contents |
Type U is swappable with type T if, for any object u of type U and any object t of type T,
| Expression | Requirements | Semantics |
|---|---|---|
| #include <algorithm> // until C++11 #include <utility> // since C++11 | After the call, the value oft is the value held byu before the call, and the value ofu is the value held byt before the call. | Calls the function namedswap() found by overload resolution among all functions with that name that are found byargument-dependent lookup and the twostd::swap templates defined in the header<algorithm>(until C++11)<utility>(since C++11). |
| #include <algorithm> // until C++11 #include <utility> // since C++11 | Same | Same |
Many standard library functions (for example, many algorithms) expect their arguments to satisfySwappable, which means that any time the standard library performs a swap, it uses the equivalent ofusingstd::swap; swap(t, u);.
Typical implementations either
It is unspecified whether<algorithm>(until C++11)<utility>(since C++11) is actually included when the standard library functions perform the swap, so the user-providedswap() should not expect it to be included.
#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();}
Output:
v1{{1, 1, 1, 1}}, v2{{2222, 2222}};v1{{2222, 2222}}, v2{{1, 1, 1, 1}};v1{{1, 1, 1, 1}}, v2{{2222, 2222}};The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
| DR | Applied to | Behavior as published | Correct behavior |
|---|---|---|---|
| LWG 226 | C++98 | it was unclear how the standard library usesswap | clarified to use bothstd:: and ADL-foundswap |
(C++17)(C++17)(C++17)(C++17) | checks if objects of a type can be swapped with objects of same or different type (class template)[edit] |
(C++20) | specifies that a type can be swapped or that two types can be swapped with each other (concept)[edit] |