• Class / Function / Type

      std::
    • Header file

      <>
    • Other / All

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

    履歴 編集

    function template
    <unordered_set>

    std::unordered_multiset::emplace

    template <class... Args>
    iterator emplace(Args&&... args);
    

    概要

    コンテナ内へ要素を直接構築する

    要件

    このコンテナの要素型 value_type は、コンテナに対して引数 args から直接構築可能(EmplaceConstructible)でなければならない。

    ここで、コンテナに対して引数 args から直接構築可能とは、m をアロケータ型 allocator_type の左辺値、p を要素型 value_type へのポインタとすると、以下の式が適格(well-formed)であるということである。

    std::allocator_traits<allocator_type>::construct(m, p, std::forward<Args>(args)...);

    効果

    std::forward<Args>(args)... から構築された value_type のオブジェクト t をコンテナに挿入する。

    なお、オブジェクト t は、構築後にコンテナにコピー、あるいはムーブされるわけではなく、コンテナ内に直接構築される。

    戻り値

    追加された要素を指すイテレータ。

    例外

    ハッシュ関数以外から例外が投げられた場合には、挿入はされない。

    計算量

    平均的なケースでは定数(O(1))だが、最悪のケースではコンテナの要素数に比例(O(size()))。

    備考

    • この関数が呼ばれた後も、当該コンテナ内の要素を指す参照は無効にはならない。
      なお、規格書に明確な記載は無いが、当該コンテナ内の要素を指すポインタも無効にはならない。

    • この関数が呼ばれた後も、呼び出しの前後でこのコンテナのバケット数(bucket_count()戻り値)が変わらなかった場合には当該コンテナを指すイテレータは無効にはならない。 それ以外の場合は、当該コンテナを指すイテレータは無効になる可能性がある。
      コンテナのバケット数が変わらない場合とは、要素追加後の要素数が、要素追加前のバケット数(bucket_count()戻り値)×最大負荷率(max_load_factor()戻り値)よりも小さかった場合である。
      なお、条件が「よりも小さい」となっているが、最大負荷率の定義からすると「以下」の方が適切と思われる。reserve も参照。

    • このメンバ関数は、コンテナの種類によってシグネチャが異なるため、注意が必要である。
      emplace_hint も含めた一覧を以下に示す。

      コンテナ シグネチャ
      シーケンスコンテナ template <class... Args>
      iterator emplace(const_iterator, Args&&...)
      連想コンテナ、非順序連想コンテナ
      (同一キーの重複を許さない場合)
      template <class... Args>
      pair<iterator, bool> emplace(Args&&...)
      連想コンテナ、非順序連想コンテナ
      (同一キーの重複を許す場合)
      template <class... Args>
      iterator emplace(Args&&...)
      連想コンテナ、非順序連想コンテナ template <class... Args>
      iterator emplace_hint(const_iterator, Args&&...)

    #include <iostream>
    #include <unordered_set>
    #include <string>
    #include <utility>
    #include <algorithm>
    #include <iterator>
    
    // サンプル用クラス
    struct is : std::pair<int, std::string> {
      is(int i, const char* s) : std::pair<int, std::string>(i, s) {}
      is(const is&) = delete; // emplace はコピーコンストラクタが無くても大丈夫
      is(is&&) = delete;      // もちろんムーブコンストラクタが無くても大丈夫
    };
    
    // サンプル用クラスのために std::hash を特殊化
    namespace std {
      template <>
      struct hash<is> : private hash<int>, private hash<string> {
        std::size_t operator()(const is& v) const {
          return hash<int>::operator()(v.first) ^ hash<string>::operator()(v.second);
        }
      };
    }
    
    // サンプル用クラスのための挿入演算子
    std::ostream& operator<<(std::ostream& os, const is& p)
    {
      return os << '(' << p.first << ',' << p.second << ')';
    }
    
    int main()
    {
      std::unordered_multiset<is> ums;
    
      auto it1 = ums.emplace(1, "1st");
      std::cout << *it1 << '\n';
      auto it2 = ums.emplace(2, "2nd");
      std::cout << *it2 << '\n';
      auto it3 = ums.emplace(1, "1st");
      std::cout << *it3 << '\n';
    
      //以下はコピー&ムーブコンストラクタが無いのでコンパイルエラーになる
      //auto it4 = ums.insert(is(3, "3rd"));
      //std::cout << *it4 << '\n';
    
      // 追加結果の出力
      std::copy(ums.cbegin(), ums.cend(), std::ostream_iterator<is>(std::cout, ", "));
      std::cout << std::endl;
    }
    

    出力

    (1,1st)
    (2,2nd)
    (1,1st)
    (2,2nd), (1,1st), (1,1st),
    

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

    バージョン

    言語

    • C++11

    処理系

    関連項目

    名前 説明
    emplace_hint 挿入位置のヒントを使用したコンテナ内への要素の直接構築
    insert 要素の追加
    erase 要素の削除
    clear 全要素の削除
    swap 内容の交換
    bucket_count バケット数の取得
    load_factor 現在の負荷率(バケットあたりの要素数の平均)を取得
    max_load_factor 最大負荷率を取得、設定
    rehash 最小バケット数指定によるバケット数の調整
    reserve 最小要素数指定によるバケット数の調整

    参照