最終更新日時(UTC): 2026年03月21日 14時12分53秒
Raclamusi が更新

履歴 編集

function
<unordered_map>

# std::unordered_map::swap(C++11)

    void swap(unordered_map& v);                                       // (1) C++11
    void swap(unordered_map& x)
      noexcept(allocator_traits<Allocator>::is_always_equal::value
                && noexcept(swap(declval<Hash&>(),declval<Hash&>()))
                && noexcept(swap(declval<Pred&>(),declval<Pred&>()))); // (1) C++17
    constexpr void swap(unordered_map& x)
      noexcept(allocator_traits<Allocator>::is_always_equal::value
                && noexcept(swap(declval<Hash&>(),declval<Hash&>()))
                && noexcept(swap(declval<Pred&>(),declval<Pred&>()))); // (1) C++26

## 概要

コンテナの内容を交換する。

## 要件

コンテナの `key_equal` と `hasher` のオブジェクト（それぞれ `key_eq()` と `hash_function()` が返すオブジェクト）は、交換可能（swappable）でなければならない。

## 効果

当該コンテナと引数で渡されたコンテナの内容を交換する。

（計算量が示すように）個々の要素それぞれに対するコピー、ムーブ、交換は行われない。

また、コンテナの `key_equal` と `hasher` のオブジェクト（それぞれ `key_eq()` と `hash_function()` が返すオブジェクト）も非メンバ関数 `swap` を非修飾で（つまり `std::` を付けずに）呼び出すことで交換される。（したがって、`swap` の呼び出しには ADL が働く。）

もし、`std::allocator_traits<allocator_type>::propagate_on_container_swap::value` が `true` であれば、アロケータオブジェクト（`get_allocator()` が返すオブジェクト）も非メンバ関数 `swap` を非修飾で呼び出すことで交換される。そうでなければアロケータオブジェクトは交換されず、その場合、当該コンテナと引数 `v` がそれぞれ `get_allocator()` で返すオブジェクトが等価でない（`operator==` が `true` を返さない）場合、未定義動作を引き起こす。

## 戻り値

なし

## 例外

コンテナの `key_equal` と `hasher` のオブジェクト（それぞれ `key_eq()` と `hash_function()` が返すオブジェクト）の `swap()` が例外を投げなければ、例外を投げない。

## 計算量

定数

## 備考

交換されたコンテナの要素を指す参照、ポインタ、および、イテレータはいずれも無効とはならずに、元の要素を指し続ける（つまり、それらの指すコンテナは入れ替わる）。なお、`end()` は要素を指さないため、無効になるかもしれない。

## 例

    #include <iostream>
    #include <unordered_map>
    #include <algorithm>
    #include <string>
    #include <utility>

    template <class C>
    void print(const char* label, const C& c, std::ostream& os = std::cout)
    {
      os << label << " : ";
      std::for_each(c.cbegin(), c.cend(), [&os](const typename C::value_type& v) { os << '(' << v.first << ", " << v.second << "), "; });
      os << '\n';
    }

    int main()
    {
      std::unordered_map<std::string, int> um1{ {"1st", 1}, {"3rd", 3}, {"5th", 5}, {"7th", 7}, {"9th", 9}, };
      std::unordered_map<std::string, int> um2{ {"0th", 0}, {"2nd", 2}, {"4th", 4}, {"6th", 6}, {"8th", 8}, };

      ::print("um1 before", um1);
      ::print("um2 before", um2);
      std::cout << std::endl;

      um1.swap(um2);

      ::print("um1 after", um1);
      ::print("um2 after", um2);
    }

### 出力例

    um1 before : (9th, 9), (7th, 7), (5th, 5), (3rd, 3), (1st, 1),
    um2 before : (8th, 8), (4th, 4), (6th, 6), (2nd, 2), (0th, 0),

    um1 after : (8th, 8), (4th, 4), (6th, 6), (2nd, 2), (0th, 0),
    um2 after : (9th, 9), (7th, 7), (5th, 5), (3rd, 3), (1st, 1),

注：`unordered_map` は非順序連想コンテナであるため、出力順序は無意味であることに注意

## バージョン

### 言語

- C++11

### 処理系

- Clang: 3.1 ✅
- GCC: 4.7.2 ✅
- ICC: ?
- Visual C++: ?

## 関連項目

名前 | 説明
--- | ---
`swap` | 内容の交換（非メンバ関数）
`emplace` | コンテナ内への要素の直接構築
`emplace_hint` | 挿入位置のヒントを使用したコンテナ内への要素の直接構築
`insert` | 要素の追加
`erase` | 要素の削除
`clear` | 全要素の削除

## 参照

- N4258 Cleaning-up noexcept in the Library, Rev 3
  - `noexcept` 追加の経緯となる提案文書
- P3372R3 constexpr containers and adaptors