function template
C++98: <algorithm>, C++11: <utility>

std::swap

template <class T> void swap (T& a, T& b);
標頭檔案
// moved from <algorithm> to <utility> in C++11
非陣列 (1)
template <class T> void swap (T& a, T& b)  noexcept (is_nothrow_move_constructible<T>::value && is_nothrow_move_assignable<T>::value);
陣列 (2)
template <class T, size_t N> void swap(T (&a)[N], T (&b)[N])  noexcept (noexcept(swap(*a,*b)));
交換兩個物件的數值
交換 ab 的值。

此函式模板的行為等同於
1
2
3
4
template <class T> void swap ( T& a, T& b )
{
  T c(a); a=b; b=c;
}

請注意,此函式涉及複製構造和兩次賦值操作,對於儲存大量資料的類的交換內容而言,這可能不是最高效的方式,因為這些操作中的每一個通常都與其大小成線性關係。

大型資料型別可以提供此函式的過載版本來最佳化其效能。特別是,所有標準容器都對其進行了專門化處理,只交換少數內部指標,而不是其全部內容,使其操作時間為常數。
此函式不再定義在標頭檔案<algorithm>中,而是在<utility>中。

這些函式模板的行為等同於
1
2
3
4
5
6
7
8
template <class T> void swap (T& a, T& b)
{
  T c(std::move(a)); a=std::move(b); b=std::move(c);
}
template <class T, size_t N> void swap (T (&a)[N], T (&b)[N])
{
  for (size_t i = 0; i<N; ++i) swap (a[i],b[i]);
}

標準庫的許多元件(在 std 名稱空間內)會以 *未限定* 的方式呼叫 swap,以允許呼叫為非基本型別宣告的自定義過載,而不是此通用版本:在為某個型別宣告的相同名稱空間中宣告的 swap 的自定義過載,透過*依賴於引數的查詢*(argument-dependent lookup)而非此通用版本來選擇。

引數

a, b
兩個物件,它們的 contents 被交換。
型別 T 必須是*可複製構造*(copy-constructible)且*可賦值*(assignable)的。
型別 T 必須是*可移動構造*(move-constructible)且*可移動賦值*(move-assignable)的(對於版本 (2),或者為其定義了 swap)。

返回值



示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// swap algorithm example (C++98)
#include <iostream>     // std::cout
#include <algorithm>    // std::swap
#include <vector>       // std::vector

int main () {

  int x=10, y=20;                              // x:10 y:20
  std::swap(x,y);                              // x:20 y:10

  std::vector<int> foo (4,x), bar (6,y);       // foo:4x20 bar:6x10
  std::swap(foo,bar);                          // foo:6x10 bar:4x20

  std::cout << "foo contains:";
  for (std::vector<int>::iterator it=foo.begin(); it!=foo.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

輸出
foo contains: 10 10 10 10 10 10


複雜度

非陣列:常數:執行一次構造和兩次賦值(儘管請注意,這些操作中的每一個都基於其自身複雜度)。
陣列:相對於 N 為線性:對每個元素執行一次交換操作。

資料競爭

ab 都被修改。

異常

如果型別 T 的構造或賦值操作丟擲異常,則此函式也丟擲異常。
如果 T 是*無丟擲移動構造*(nothrow-move-constructible)且*無丟擲移動賦值*(nothrow-move-assignable)的,則此函式永不丟擲異常。
請注意,如果 T 不滿足上面(在 parameters 中)指定的要求,則會導致*未定義行為*(undefined behavior)。

另見