最終更新日時(UTC): 2026年02月17日 14時22分33秒
Akira Takahashi が更新

履歴 編集

function
<map>

# std::multimap::コンストラクタ

    multimap();           // (1) C++14
    constexpr multimap(); // (1) C++26

    explicit
      multimap(const Compare& comp,
               const Allocator& alloc = Allocator()); // (2) C++14
    constexpr explicit
      multimap(const Compare& comp,
               const Allocator& alloc = Allocator()); // (2) C++26

    explicit multimap(const Compare& comp = Compare(),
                      const Allocator& alloc = Allocator()); // (1) + (2) C++11 まで

    explicit multimap(const Allocator& alloc);               // (3) C++11
    constexpr explicit multimap(const Allocator& alloc);     // (3) C++26

    template <class InputIterator>
    multimap(InputIterator first,
             InputIterator last,
             const Compare& comp = Compare(),
             const Allocator& alloc = Allocator());    // (4) C++03
    template <class InputIterator>
    constexpr
      multimap(InputIterator first,
               InputIterator last,
               const Compare& comp = Compare(),
               const Allocator& alloc = Allocator());  // (4) C++26

    template <class InputIterator>
    multimap(InputIterator first,
             InputIterator last,
             const Allocator& alloc);    // (5) C++14
    template <class InputIterator>
    constexpr
      multimap(InputIterator first,
               InputIterator last,
               const Allocator& alloc);  // (5) C++26

    multimap(const multimap& x);           // (6) C++03
    constexpr multimap(const multimap& x); // (6) C++26

    multimap(const multimap& x,
             const Allocator& alloc);                    // (7) C++11
    multimap(const multimap& x,
             const type_identity_t<Allocator>& alloc);   // (7) C++23
    constexpr
      multimap(const multimap& x,
               const type_identity_t<Allocator>& alloc); // (7) C++26

    multimap(multimap&& y);           // (8) C++11
    constexpr multimap(multimap&& y); // (8) C++26

    multimap(multimap&& y,
             const Allocator& alloc);                    // (9) C++11
    multimap(multimap&& y,
             const type_identity_t<Allocator>& alloc);   // (9) C++23
    constexpr
      multimap(multimap&& y,
               const type_identity_t<Allocator>& alloc); // (9) C++26

    multimap(initializer_list<value_type> init,
             const Compare& comp = Compare(),
             const Allocator& alloc = Allocator());    // (10) C++11
    constexpr
      multimap(initializer_list<value_type> init,
               const Compare& comp = Compare(),
               const Allocator& alloc = Allocator());  // (10) C++26

    multimap(initializer_list<value_type> init,
             const Allocator& alloc);                  // (11) C++14
    constexpr
      multimap(initializer_list<value_type> init,
               const Allocator& alloc);                // (11) C++26

    template <container-compatible-range <value_type> R>
    multimap(from_range_t,
             R&& rg,
             const Compare& comp = Compare(),
             const Allocator& alloc = Allocator());    // (12) C++23
    template <container-compatible-range <value_type> R>
    constexpr
      multimap(from_range_t,
               R&& rg,
               const Compare& comp = Compare(),
               const Allocator& alloc = Allocator());  // (12) C++26

    template <container-compatible-range <value_type> R>
    multimap(from_range_t,
             R&& rg,
             const Allocator& alloc);                  // (13) C++23
    template <container-compatible-range <value_type> R>
    constexpr
      multimap(from_range_t,
               R&& rg,
               const Allocator& alloc);                // (13) C++26

## 概要

`multimap` オブジェクトを構築する

## 効果

- (1) デフォルトコンストラクタ。空の `multimap` オブジェクトを構築する。`multimap(Compare())` と等価。（C++14 から）
- (2) 比較オブジェクト `comp` とアロケータ `alloc` で空の `multimap` オブジェクトを構築する。（C++14 から）
- (1) + (2) デフォルトコンストラクタ。比較オブジェクト `comp` とアロケータ `alloc` で空の `multimap` オブジェクトを構築する。（C++11 まで）
- (3) アロケータ `alloc` で空の `multimap` オブジェクトを構築する。（C++11 から）
- (4) イテレータ範囲コンストラクタ。比較オブジェクト `comp`、アロケータ `alloc`、および範囲 `[first, last)` の要素で `multimap` オブジェクトを構築する。
- (5) イテレータ範囲コンストラクタ。アロケータ `alloc`、および範囲 `[first, last)` の要素で `multimap` オブジェクトを構築する。（C++14 から）
- (6) コピーコンストラクタ。`x` の要素のコピーで `multimap` オブジェクトを構築する。アロケータは `std::allocator_traits<allocator_type>::select_on_container_copy_construction(x)` の呼び出しによって取得する。
- (7) アロケータ `alloc` を指定したコピーコンストラクタ。`x` の要素のコピーで `multimap` オブジェクトを構築する。（C++11 から）
- (8) ムーブコンストラクタ。`y` の要素をムーブすることで `multimap` オブジェクトを構築する。アロケータは `y` に属しているアロケータをムーブして取得する。（C++11 から）
- (9) アロケータ `alloc` を指定したムーブコンストラクタ。`y` の要素をムーブすることでコンテナを構築する。（C++11 から）
- (10) 比較オブジェクト `comp`、アロケータ `alloc`、および初期化リスト `init` の要素で `multimap` オブジェクトを構築する。`multimap(init.begin, init.end, comp, alloc)` と等価。（C++11 から）
- (11) アロケータ `alloc`、および初期化リスト `init` の要素で `multimap` オブジェクトを構築する。`multimap(init, Compare(), alloc)` と等価。（C++14 から）
- (12) Rangeコンストラクタ。比較オブジェクト `comp`、アロケータ `alloc` 、およびRange `rg` の要素で `multimap` オブジェクトを構築する。
- (13) Rangeコンストラクタ。アロケータ `alloc` 、およびRange `rg` の要素で `multimap` オブジェクトを構築する。

## 計算量

- (1), (2), (3) 定数時間
- (4), (5) `N = distance(first, last)` とすると、範囲 `[first, last)` が比較オブジェクト `comp` によって既にソート済みである場合は `N` に比例、そうでなければ `N log N` に比例
- (6), (7) `x.size()` に対して線形時間
- (8) 定数時間
- (9) 定数時間。ただし、`alloc == y.get_allocator()` でなければ `y.size()` に対して線形時間
- (10), (11) `N = init.size()` とすると、範囲 `[init.begin(), init.end())` が比較オブジェクト `comp` によって既にソート済みである場合は `N` に比例、そうでなければ `N log N` に比例
- (12), (13) `N = ranges::distance(rg)` とすると、`rg` が比較オブジェクト `comp` によって既にソート済みである場合は `N` に比例、そうでなければ `N log N` に比例

## 備考

- C++14 では、デフォルトコンストラクタを (1) + (2) の形式から (1) の形式に分離して残りを (2) の形式（`comp` のデフォルト引数を削除）にした。 これは、デフォルトコンストラクタに `explicit` が付いていると、

      std::multimap<int, char> m = {};

  のようなコード（C++11 から導入された、コピーリスト初期化によるデフォルトコンストラクタ呼び出し）がエラーになってしまうためである。

- C++14 では、(5) の形式が新たに追加された。 これは、イテレータ範囲 `[first, last)` のみを引数にとるアロケータ使用構築（uses-allocator construction）に失敗してしまうためである。 具体的には、C++11 では以下のようなコードがエラーになってしまう。

      #include <list>
      #include <map>
      #include <scoped_allocator>
      #include <iterator>
      #include <utility>
      #include <memory>

      int main()
      {
        using mii = std::multimap<int, int>;
        std::list<mii, std::scoped_allocator_adaptor<std::allocator<mii>>> ls;
        std::pair<const int, int> a[] = { { 1, 2 }, { 3, 4 }, { 5, 6 } };
        ls.emplace_back(std::begin(a), std::end(a));
      }

  なお、C++14 では同様の理由で (11) の形式も新たに追加されているが、こちらは存在しなくてもエラーとはならない。
  （`multimap(init, alloc)` の形式の構築では、(11) の形式が無い場合でも (10) の形式を用いて `init` から一時 `multimap` が構築され、`alloc` と共に (9) の形式に引き渡される）

- C++23 では、(7) と (9) のアロケータパラメータの型が `const Allocator&` から `const type_identity_t<Allocator>&` に変更された。 これは、クラステンプレートのテンプレート引数推論 (CTAD) の際に、コピー/ムーブ元の `multimap` から推論される `Allocator` と、アロケータ引数から推論される型が異なる場合に推論が失敗する問題を修正するためである。`type_identity_t` で包むことで、アロケータ引数が非推論コンテキストとなり、アロケータの型はコピー/ムーブ元のみから推論されるようになる。

## 例

    #include <iostream>
    #include <map>

    int main()
    {
      std::pair<int,char> values[] = { std::make_pair(1,'a'), std::make_pair(2,'b'), std::make_pair(2,'b') };
      std::multimap<int,char> m1(values, values + 3);
      std::multimap<int,char> m2(m1);

      std::cout << "Size of m1: " << m1.size() << std::endl;
      std::cout << "Size of m2: " << m2.size() << std::endl;
    }

### 出力

    Size of m1: 3
    Size of m2: 3

### 処理系

- Clang: ??
- GCC: ??
- ICC: ??
- Visual C++: 2012 ✅

## 関連項目

名前 | 説明
--- | ---
`operator=` | 代入演算子
`insert` | 要素を挿入する

## 参照

- N2679 Initializer Lists for Standard Containers(Revision 1)
  - (10)の経緯となる提案文書
- LWG 2193. Default constructors for standard library containers are explicit
  (1) + (2) の形式を 2 つのオーバーロードに分割するきっかけとなったレポート
- LWG 2210. Missing allocator-extended constructor for allocator-aware containers
  (5), (11) の形式を追加するきっかけとなったレポート
  なお、Discussion の例はアロケータの型が誤っているので注意
- P1518R2 Stop Overconstraining Allocators in Container Deduction Guides
  - C++23でのアロケータ引数を`type_identity_t`で包む変更
- P3372R3 constexpr containers and adaptors