std::swap
來自 cppreference.com
定義於標頭檔案 <algorithm> |
(C++11 前) |
|
在標頭檔案 <utility> 中定義 |
(C++11 起) |
|
定義於標頭檔案 <string_view> |
||
template< class T > void swap( T& a, T& b ); |
(1) | (C++11 起有條件 noexcept) (C++20 起為 constexpr) |
template< class T2, std::size_t N > void swap( T2 (&a)[N], T2 (&b)[N] ); |
(2) | (C++11 起有條件 noexcept) (C++20 起為 constexpr) |
交換給定的值。
1) 交換 a 和 b 的值。
僅若 std::is_move_constructible_v<T> && std::is_move_assignable_v<T> 為 true 時,此過載才會參與過載決議。 |
(C++17 起) |
2) 交換陣列 a 和 b。等價於 std::swap_ranges(a, a + N, b)。
僅若 std::is_swappable_v<T2> 為 true 時,此過載才會參與過載決議。 |
(C++17 起) |
目錄 |
[編輯] 引數
a, b | - | 要交換的值 |
型別要求 | ||
-T 必須滿足 可複製構造 (CopyConstructible) 和 可複製賦值 (CopyAssignable) (C++11 前) 可移動構造 (MoveConstructible) 和 可移動賦值 (MoveAssignable) (C++11 起) 的要求。 | ||
-T2 必須滿足 可交換 (Swappable) 的要求。 |
[編輯] 返回值
(無)
[編輯] 異常
1)
(無) |
(C++11 前) |
noexcept 規範:
noexcept( std::is_nothrow_move_constructible<T>::value && |
(C++11 起) |
2)
noexcept 規範: 在異常說明中查詢識別符號 noexcept(noexcept(swap(*a, *b))) swap 時,除了按常規查詢規則找到的內容外,還會找到此函式模板,這使得異常說明等價於 C++17 的 std::is_nothrow_swappable。 |
(C++11 起) (C++17 前) |
noexcept 規範:
noexcept(std::is_nothrow_swappable_v<T2>) |
(C++17 起) |
[編輯] 複雜度
1) 常數。
2) 與 N 成線性。
[編輯] 特化
可以在名稱空間 std 中為程式定義型別特化 |
(C++20 前) |
使程式定義型別可交換的預期方法是,在該型別所在的名稱空間中提供一個非成員函式 swap:詳見可交換 (Swappable) 。
標準庫已經提供了以下過載
(C++11) |
特化 std::swap 演算法 (函式模板) |
(C++11) |
特化 std::swap 演算法 (函式模板) |
(C++11) |
特化 std::swap 演算法 (函式模板) |
(C++11) |
特化 std::swap 演算法 (函式模板) |
(C++11) |
特化 std::swap 演算法 (函式模板) |
(C++11) |
特化 std::swap 演算法 (函式模板) |
特化 std::swap 演算法 (函式模板) | |
(C++11) |
特化 std::swap 演算法 (函式模板) |
特化 std::swap 演算法 (函式模板) | |
(C++11) |
特化 std::swap 演算法 (函式模板) |
特化 std::swap 演算法 (函式模板) | |
特化 std::swap 演算法 (函式模板) | |
特化 std::swap 演算法 (函式模板) | |
特化 std::swap 演算法 (函式模板) | |
特化 std::swap 演算法 (函式模板) | |
特化 std::swap 演算法 (函式模板) | |
特化 std::swap 演算法 (函式模板) | |
特化 std::swap 演算法 (函式模板) | |
特化 std::swap 演算法 (函式模板) | |
特化 std::swap 演算法 (函式模板) | |
(C++11) |
特化 std::swap 演算法 (函式模板) |
特化 std::swap 演算法 (函式模板) | |
(C++11) |
特化 std::swap 演算法 (函式模板) |
(C++11) |
特化 std::swap 演算法 (函式模板) |
特化 std::swap 演算法 (函式模板) | |
特化 std::swap 演算法 (函式模板) | |
特化 std::swap 演算法 (函式模板) | |
特化 std::swap 演算法 (函式模板) | |
特化 std::swap 演算法 (函式模板) | |
特化 std::swap 演算法 (函式模板) | |
特化 std::swap 演算法 (函式模板) | |
特化 std::swap 演算法 (函式模板) | |
特化 std::swap 演算法 (函式模板) | |
特化 std::swap 演算法 (函式模板) | |
特化 std::swap 演算法 (函式模板) | |
特化 std::swap 演算法 (函式模板) | |
特化 std::swap 演算法 (函式模板) | |
(C++11) |
特化 std::swap 演算法 (函式模板) |
特化 std::swap 演算法 (函式模板) | |
(C++11) |
特化 std::swap 演算法 (函式) |
(C++11) |
特化 std::swap 演算法 (函式模板) |
(C++14) |
特化 std::swap 演算法 (函式模板) |
(C++11) |
特化 std::swap 演算法 (函式模板) |
特化 std::swap 演算法 (函式模板) | |
(C++17) |
特化 std::swap 演算法 (函式模板) |
(C++17) |
特化 std::swap 演算法 (函式) |
(C++17) |
特化 std::swap 演算法 (函式模板) |
特化 std::swap 演算法 (函式模板) | |
(C++17) |
特化 std::swap 演算法 (函式) |
(C++23) |
特化 std::swap 演算法 (函式) |
(C++20) |
特化 std::swap 演算法 (函式) |
特化 std::swap 演算法 (函式) | |
(C++20) |
特化 std::swap 演算法 (函式) |
(C++20) |
特化 std::swap 演算法 (函式) |
[編輯] 示例
執行此程式碼
#include <algorithm> #include <iostream> namespace Ns { class A { int id {}; friend void swap(A& lhs, A& rhs) { std::cout << "swap(" << lhs << ", " << rhs << ")\n"; std::swap(lhs.id, rhs.id); } friend std::ostream& operator<<(std::ostream& os, A const& a) { return os << "A::id=" << a.id; } public: A(int i) : id {i} {} A(A const&) = delete; A& operator = (A const&) = delete; }; } int main() { int a = 5, b = 3; std::cout << a << ' ' << b << '\n'; std::swap(a, b); std::cout << a << ' ' << b << '\n'; Ns::A p {6}, q {9}; std::cout << p << ' ' << q << '\n'; // std::swap(p, q); // error, type requirements are not satisfied swap(p, q); // OK, ADL finds the appropriate friend `swap` std::cout << p << ' ' << q << '\n'; }
輸出
5 3 3 5 A::id=6 A::id=9 swap(A::id=6, A::id=9) A::id=9 A::id=6
[編輯] 缺陷報告
下列更改行為的缺陷報告追溯地應用於以前出版的 C++ 標準。
缺陷報告 | 應用於 | 釋出時的行為 | 正確的行為 |
---|---|---|---|
LWG 227 | C++98 | T 未被要求為可複製構造的 (CopyConstructible) 或可預設構造的 (DefaultConstructible) (型別 T 的臨時物件可能無法構造) |
T 也要求為可複製構造 (CopyConstructible) |
LWG 809 | C++98 | 陣列不能被交換 | 添加了過載 (2) |
LWG 2554 | C++11 | 交換多維陣列永遠不能 由於名稱查詢問題而為 noexcept |
已修復 |
[編輯] 參閱
(C++20) |
交換兩個物件的值 (自定義點物件) |
交換兩個迭代器所指向的元素 (函式模板) | |
交換兩個範圍的元素 (函式模板) | |
(C++14) |
用新值替換引數並返回其舊值 (函式模板) |