Skip to content

Latest commit

 

History

History
165 lines (127 loc) · 4.01 KB

swap.md

File metadata and controls

165 lines (127 loc) · 4.01 KB

swap

  • utility[meta header]
  • std[meta namespace]
  • function template[meta id-type]
  • cpp11[meta cpp]
namespace std {
  template <class T>
  void swap(T& a, T& b);                               // (1) C++03 in <algorithm> header

  template <class T>
  void swap(T& a, T& b) noexcept(see below);           // (1) C++11

  template <class T>
  constexpr void swap(T& a, T& b) noexcept(see below); // (1) C++20

  template <class T, size_t N>
  void swap(T (&a)[N], T (&b)[N])
                     noexcept(noexcept(swap(*a, *b))); // (2) C++11

  template <class T, size_t N>
  constexpr void swap(T (&a)[N], T (&b)[N])
                     noexcept(noexcept(swap(*a, *b))); // (2) C++20
}
  • see below[italic]

概要

2つの値を入れ替える。

要件

  • 値版:型TMoveConstructibleかつMoveAssignableでなければならない。
  • 配列版:範囲[0, N)内の全てのiにおいて、a[i]b[i]Swappableでなければならない。

効果

値版の振る舞いは、以下のコードと等価である:

template <class T>
void swap(T& a, T& b) {
  T t = std::move(a);
  a = std::move(b);
  b = std::move(t);
}
  • std::move[link move.md]

配列版の振る舞いは、以下のコードと等価である:

template <class T, size_t N>
void swap(T (&a)[N], T (&b)[N]) {
  for (std::size_t i = 0; i < N; ++i) {
    swap(a[i], b[i]);
  }
}

つまり、範囲[0, N)内の全てのiについて、 swap(a[i], b[i]); を呼び出す。

この関数の内部におけるswap()呼び出しは、 std::swap(a[i], b[i]); という形ではなく、 swap(a[i], b[i]); という形で行われる。すなわち、T型に対してオーバーロードされたswap()関数がある場合には、常にそちらが呼ばれる。

そのため、swap()関数を呼び出す場合は、直接std::swap(a, b);と呼び出すのではなく、

using std::swap;
swap(a, b);

のように呼び出し、各クラスに対し個別に定義された swap がある場合には そちらが呼ばれるようにするべきである。

戻り値

なし

例外

  • 値版:noexcept中の式は、以下と等価である:is_nothrow_move_constructible<T>::value && is_nothrow_move_assignable<T>::value
  • 配列版:配列の要素型Tに対するswap()操作が例外を投げない場合、この関数もまた例外を投げない

備考

C++03では<algorithm>ヘッダに定義されていた。

#include <iostream>
#include <utility>

template <class Array>
void print(const Array& ar)
{
  std::cout << '[';
  bool first = true;
  for (auto x : ar) {
    if (first) {
      first = false;
    }
    else {
      std::cout << ',';
    }
    std::cout << x;
  }
  std::cout << ']';
}

int main()
{
  // 値版
  {
    int a = 1;
    int b = 2;

    using std::swap;
    swap(a, b);

    std::cout << a << ", " << b << std::endl;
  }

  // 配列版
  {
    int a[] = {1, 2, 3};
    int b[] = {4, 5, 6};

    using std::swap;
    swap(a, b);

    print(a);
    std::cout << ", ";
    print(b);
    std::cout << std::endl;
  }
}
  • swap[color ff0000]

出力

2, 1
[4,5,6], [1,2,3]

バージョン

言語

  • C++11

処理系

  • Clang: ??
  • GCC: 4.7.0 [mark verified]
  • ICC: ??
  • Visual C++: 2012 [mark verified], 2013 [mark verified], 2015 [mark verified]
    • 値版はそれより前から実装されている。

関連項目

参照