最終更新日時(UTC):
が更新

履歴 編集

function
<set>

std::multiset::コンストラクタ

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

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

explicit multiset(const Compare& comp = Compare(),
                  const Allocator& alloc = Allocator()); // (1) + (2) C++03

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

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

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

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

multiset(set&& y);           // (7) C++11
constexpr multiset(set&& y); // (7) C++26

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

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

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

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

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

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

概要

multisetオブジェクトを、以下に示す通りの要素で初期化する。

効果

  • (1) : デフォルトコンストラクタ。要素数が空のmultisetオブジェクトを構築する。
  • (2) : 比較関数オブジェクトを受け取るコンストラクタ。受け取った比較関数オブジェクトを、このコンテナでの要素比較に使用する。要素数が空のmultisetオブジェクトを構築する。
  • (1) + (2) : デフォルトコンストラクタ。空のコンテナを構築する。
  • (3) : アロケータを別で受け取り、要素数が空のmultisetオブジェクトを構築する。
  • (4) : 範囲 [first, last) のコンテンツで構築する。
  • (5) : (4)のコンストラクタを multiset(first, last, Compare(), a) のように呼び出して、multisetオブジェクトを構築する。
  • (6), (8) : コピーコンストラクタ。xのコンテンツのコピーでコンテナを構築する。もし alloc が与えられなかった場合、アロケータを std::allocator_traits<allocator_type>::select_on_container_copy_construction(x.get_allocator()) の呼び出しによって取得する。
  • (7), (9) : ムーブコンストラクタ。y のコンテンツをムーブすることでコンテナを構築する。もし alloc が与えられなかった場合、アロケータを y に属しているアロケータをムーブして取得する。
  • (10) : 初期化リスト init のコンテンツでコンテナを構築する。
  • (11) : (10)のコンストラクタを multiset(init, Compare(), a) のように呼び出して、multisetオブジェクトを構築する。
  • (12) : Range rg の要素で multiset オブジェクトを構築する。
  • (13) : (12)のコンストラクタを multiset(from_range, rg, Compare(), alloc) のように呼び出して、multisetオブジェクトを構築する。

計算量

  • (1), (2), (3) : 定数時間。
  • (4), (5) : comp によって既にソート済みである場合は、イテレータ間の距離(コピーコンストラクト)。未ソートのシーケンスの場合は、それらの距離について N * logN (ソート、コピーコンストラクト)。
  • (6), (8) : xsize に対して線形時間(全要素をコピー構築する)。
  • (7), (9) : 定数時間。ただし、alloc が与えられてかつ alloc != y.get_allocator() の場合は線形時間。
  • (10), (11) : comp によって既にソート済みである場合は、init のサイズ(コピーコンストラクト)。未ソートの init の場合は、init のサイズについて N * logN (ソート、コピーコンストラクト)。
  • (12), (13) : comp によって既にソート済みである場合は、rg のサイズ(コピーコンストラクト)。未ソートの rg の場合は、rg のサイズについて N * logN (ソート、コピーコンストラクト)。

備考

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

    std::multiset<int> s = {};
    

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

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

    #include <list>
    #include <set>
    #include <scoped_allocator>
    #include <iterator>
    #include <memory>
    
    int main()
    {
      using sii = std::multiset<int>;
      std::list<sii, std::scoped_allocator_adaptor<std::allocator<sii>>> ls;
      int a[] = {1, 2, 3};
      ls.emplace_back(std::begin(a), std::end(a));
    }
    

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

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

#include <iostream>
#include <set>

int main()
{
  int values[] = { 5, 2, 4, 1, 0, 0, 9 };
  std::multiset<int> c1(values, values + 7);
  std::multiset<int> c2(c1);

  std::cout << "Size of c1: " << c1.size() << std::endl;
  std::cout << "Size of c2: " << c2.size() << std::endl;
}

出力

Size of c1: 7
Size of c2: 7

関連項目

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

参照