• Class / Function / Type

      std::
    • Header file

      <>
    • Other / All

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

    履歴 編集

    function
    <set>

    std::multiset::erase

    void erase(iterator position);                             // (1) C++03 (C++11で一旦削除)
    iterator erase(iterator position);                         // (1) C++17
    
    iterator erase(const_iterator position);                   // (2) C++11
    
    size_type erase(const key_type& x);                        // (3) C++03
    
    template <class K>
    size_type erase(K&& x);                                    // (4) C++23
    
    void erase(iterator first, iterator last);                 // (5) C++03
    iterator erase(const_iterator first, const_iterator last); // (5) C++11
    

    概要

    単一要素またはイテレータ範囲[first, last)multiset コンテナから削除する。 これは削除された要素の数だけコンテナの size() を減らし、それぞれの要素のデストラクタを呼び出す。

    • (1) : 指定されたイテレータが指す要素を削除する
    • (2) : 指定された読み取り専用イテレータが指す要素を削除する
    • (3) : 指定されたキーをもつ要素をすべて削除する
    • (4) : key_typeと比較可能なK型のキーを受け取って要素をすべて削除する
    • (5) : 指定されたイテレータ範囲の要素をすべて削除する

    パラメータ

    • position : multiset から削除する単一要素を指すイテレータ。iterator、および、const_iterator はメンバ型であり、双方向イテレータとして定義される。
    • x : multiset から削除される値。key_type はメンバ型であり、multiset コンテナの中で Key の別名として定義される。ここで Key は 1 番目のテンプレートパラメータであり、コンテナに格納される要素の型である。
    • first, last : multiset コンテナ内の、削除されるイテレータ範囲 [first, last) を指定するイテレータ。ここでいう範囲は firstlast の間の全ての要素を含み、first が指す要素を含むが last が指す要素は含まない。

    戻り値

    • (1) :
      • C++03 : 戻り値なし
      • C++17 : 削除された要素の次を指すイテレータを返す。そのような要素がない場合、end()を返す (要素を削除した結果としてコンテナが空になった場合)
    • (2) : 削除された要素の次を指すイテレータを返す。そのような要素がない場合、end()を返す (要素を削除した結果としてコンテナが空になった場合)
    • (3), (4) : 削除された要素の数を返す
    • (5) :
      • C++03 : 戻り値なし
      • C++11 : 削除された要素の次を指すイテレータを返す。そのような要素がない場合、end()を返す (要素を削除した結果としてコンテナが空になった場合)

    計算量

    • (1), (2) : 定数時間
    • (3), (4) : コンテナの size() について対数時間に加えて、count(x)について線形時間
    • (5) : コンテナの size() について対数時間、それに加えて firstlast の間の距離に対する線形時間

    備考

    • (1) : C++17で再追加されたこのオーバーロードは、それ以前の言語バージョンから使用できる可能性がある
    • (1), (2) : この関数に、範囲外のイテレータ (終端イテレータを含む) を指定した場合の動作は未定義
    • 削除された要素を指すイテレータ、および、参照のみ無効になる。なお、規格書に明確な記載は無いが、削除された要素を指すポインタも無効になる。
    • ループ中で multiset の要素を削除するためには、C++03 までは以下のようなコードを書く必要があった。

      while (it != set_object.end()) {
        if (条件) {
          set_object.erase(it++);
        }
        else {
          ++it;
        }
      }
      

      • これは、erase で指定したイテレータが、対象となる要素が削除されることによって無効になるため、後置インクリメント it++ を使用することで要素が削除されるより先に削除対象の次の要素を指すようにするためである。
      • このような書き方は C++11 以降でも依然として有効だが、erase が削除された次の要素を指すイテレータを返すようになったため、以下のようなコードを

      set_object.erase(it++);
      

      • 以下のように書くこともできるようになった

      it = set_object.erase(it);
      

    基本的な使い方 (C++03)

    #include <iostream>
    #include <set>
    
    int main()
    {
      std::multiset<int> c;
    
      c.insert(10);
      c.insert(10);
      c.insert(30);
      std::cout << c.size() << std::endl;
    
      c.erase(10);
      std::cout << c.size() << std::endl;
    
      c.erase(c.begin(), c.end());
      std::cout << c.size() << std::endl;
    }
    

    出力

    3
    1
    0
    

    イテレート中に要素を削除する (C++11)

    #include <iostream>
    #include <set>
    
    int main()
    {
      std::multiset<int> c = {3, 1, 4};
    
      // イテレート中に要素削除をするような場合には、
      // 範囲for文は使用できない
      for (auto it = c.begin(); it != c.end();) {
        // 条件一致した要素を削除する
        if (*it == 1) {
          // 削除された要素の次を指すイテレータが返される。
          // C++03では、erase()の戻り値を使用せず、 c.erase(it++); のように書く
          it = c.erase(it);
        }
        // 要素削除をしない場合に、イテレータを進める
        else {
          ++it;
        }
      }
    
      for (const auto& x : c) {
        std::cout << x << std::endl;
      }
    }
    

    出力

    3
    4
    

    関連項目

    名前 説明
    clear 全ての要素を削除する
    insert 要素を挿入する
    find 指定したキーで要素を探す

    参照