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

履歴 編集

function
<unordered_set>

std::unordered_multiset::erase

iterator erase(iterator position);                         // (1) C++17

iterator erase(const_iterator position);                   // (2) C++11

size_type erase(const key_type& k);                        // (3) C++11

iterator erase(const_iterator first, const_iterator last); // (4) C++11

概要

指定された要素を削除する

要件

  • position は、有効で、かつ、間接参照可能な(dereferenceable、つまり cend() ではない)当該コンテナを指す読み取り専用イテレータでなければならない。
  • firstlast[first, last) が当該コンテナの有効な範囲である読み取り専用イテレータでなければならない。
    なお、規格書では first は間接参照可能である必要があることになっているが、他の種類のコンテナの要件と照らし合わせると、間接参照可能である必要はない(つまり、firstlast が共に cend() でも良い)ものと思われる。

効果

  • (1), (2) : position で指定された要素を削除する。
  • (3) : k と等価なキーの要素を削除する。
  • (4) : イテレータ範囲[first, last)にある要素を全て削除する。

戻り値

  • (1), (2) : 「削除前に、削除された要素の次だった位置」を指すイテレータ。erase() を呼び出しても削除された要素以外を指す全てのイテレータは無効にならないため、std::next(position) と同じ位置を指す iterator である。
    なお、positionconst_iterator なのに対して、戻り値は iterator であるため注意が必要だが、非順序連想コンテナの場合いずれにせよどちらも読み取り専用イテレータである。
  • (3) : 削除した要素数。
  • (4) : 「削除前に、削除された要素の範囲の次だった位置」を指すイテレータ。erase() を呼び出しても削除された要素以外を指す全てのイテレータは無効にならないため、last と同じ位置を指す iterator である。
    なお、first 及び lastconst_iterator なのに対して、戻り値は iterator であるため注意が必要だが、非順序連想コンテナの場合いずれにせよどちらも読み取り専用イテレータである。
    また、要件に示したように first が間接参照可能である必要がなかった場合にも、他の種類のコンテナの戻り値と照らし合わせると、last と同じ位置を指す iterator を返すのが適切であるものと思われる。

例外

  • (1), (2) : 投げない。
  • (3) : コンテナの key_equalhasher のオブジェクト(それぞれ key_eq()hash_function() が返すオブジェクト)が例外を投げなければ、例外を投げない。
  • (4) : 投げない。

計算量

  • (1), (2) : 平均的なケースでは定数(O(1))だが、最悪のケースではコンテナの要素数に比例(O(size()))
  • (3) : 平均的なケースでは削除された要素数に比例(O(count(k)))だが、最悪のケースではコンテナの要素数に比例(O(size()))
  • (4) : 平均的なケースでは指定された範囲の要素数に比例(O(std::distance(first, last)))だが、最悪のケースではコンテナの要素数に比例(O(size()))

備考

削除された要素を指すイテレータ、および、参照のみ無効になる。なお、規格書に明確な記載は無いが、削除された要素を指すポインタも無効になる。

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

#include <iostream>
#include <unordered_set>
#include <iterator>
#include <algorithm>

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

int main()
{
  // 指定した位置にある要素を削除((1)の形式)
  {
    std::unordered_multiset<int> ums{ 1, 3, 5, 7, 9, 3, };
    print("(1) erase(const_iterator) before", ums);

    auto it1 = std::next(ums.cbegin(), 3);
    std::cout << "argument: " << *it1 << '\n';
    auto it2 = ums.erase(it1);
    std::cout << "return value: " << *it2 << '\n';
    print("after", ums);
    std::cout << std::endl;
  }

  // 指定したキーと等価な要素を削除((3)の形式)
  {
    std::unordered_multiset<int> ums{ 1, 3, 5, 7, 9, 3, };
    print("(3) erase(const value_type&) before", ums);

    auto count1 = ums.erase(5);
    auto count2 = ums.erase(8);
    auto count3 = ums.erase(3);
    std::cout << "argument: 5, 8, 3" << '\n';
    std::cout << "return value: " << count1 << ", " << count2 << ", " << count3 << std::endl;
    print("after", ums);
    std::cout << std::endl;
  }

  // 指定した位置にある要素を削除((4)の形式)
  {
    std::unordered_multiset<int> ums{ 1, 3, 5, 7, 9, 3, };
    print("(4) erase(const_iterator, const_iterator) before", ums);

    auto it1 = std::next(ums.cbegin());
    auto it2 = std::next(it1, 2);
    std::cout << "arguments: " << *it1 << ", " << *it2 << '\n';
    auto it3 = ums.erase(it1, it2);
    std::cout << "return value: " << *it3 << '\n';
    print("after", ums);
    std::cout << std::endl;
  }
}

出力例

(1) erase(const_iterator) before : 9 7 5 1 3 3
argument: 1
return value: 3
after : 9 7 5 3 3

(3) erase(const value_type&) before : 9 7 5 1 3 3
argument: 5, 8, 3
return value: 1, 0, 2
after : 9 7 1

(4) erase(const_iterator, const_iterator) before : 9 7 5 1 3 3
arguments: 7, 1
return value: 1
after : 9 1 3 3

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

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

#include <iostream>
#include <unordered_set>

int main()
{
  std::unordered_multiset<int> ums = {3, 1, 4};

  // イテレート中に要素削除をするような場合には、
  // 範囲for文は使用できない
  for (auto it = ums.begin(); it != ums.end();) {
    // 条件一致した要素を削除する
    if (*it == 1) {
      // 削除された要素の次を指すイテレータが返される
      it = ums.erase(it);
    }
    // 要素削除をしない場合に、イテレータを進める
    else {
      ++it;
    }
  }

  for (const auto& x : ums) {
    std::cout << x << std::endl;
  }
}

出力例

4
3

バージョン

言語

  • C++11

処理系

関連項目

名前 説明
emplace コンテナ内への要素の直接構築
emplace_hint 挿入位置のヒントを使用したコンテナ内への要素の直接構築
insert 要素の追加
clear 全要素の削除
swap 内容の交換

参照