void erase(iterator position); // (1) C++03 まで
iterator erase(const_iterator position); // (1) C++11 から
void erase(iterator first, iterator last); // (2) C++03 まで
iterator erase(const_iterator first, const_iterator last); // (2) C++11 から
size_type erase(const key_type& x); // (3)
概要
単一要素またはイテレータ範囲[first, last)
を set
コンテナから削除する。
これは削除された要素の数だけコンテナの size()
を減らし、それぞれの要素のデストラクタを呼び出す。
パラメータ
position
:set
から削除する単一要素を指すイテレータ。iterator
、および、const_iterator
はメンバ型であり、双方向イテレータとして定義される。x
:set
から削除される値。key_type
はメンバ型であり、set
コンテナの中でKey
の別名として定義される。ここでKey
は 1 番目のテンプレートパラメータであり、コンテナに格納される要素の型である。first, last
:set
コンテナ内の、削除されるイテレータ範囲[first, last)
を指定するイテレータ。ここでいう範囲はfirst
とlast
の間の全ての要素を含み、first
が指す要素を含むがlast
が指す要素は含まない。
戻り値
- (1), (2) :
- C++03 まで : なし
- C++11 から : 削除された要素の次を指すイテレータを返す。そのような要素がない場合、
end()
を返す(コンテナが空になった場合や、最後尾の要素を削除した場合)。
- (3) : 削除された要素の数を返す。
計算量
- (1) : 定数時間
- (2) : コンテナの
size()
についての対数時間と、それに加えてfirst
とlast
の間の距離に対する線形時間。 - (3) : コンテナの
size()
について対数時間。
備考
- 削除された要素を指すイテレータ、および、参照のみ無効になる。なお、規格書に明確な記載は無いが、削除された要素を指すポインタも無効になる。
-
ループ中で
set
の要素を削除するためには、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::set<int> c;
c.insert(10);
c.insert(20);
c.insert(30);
std::cout << c.size() << std::endl;
c.erase(10);
std::cout << c.size() << std::endl;
c.erase(5);
std::cout << c.size() << std::endl;
c.erase(c.begin(), c.end());
std::cout << c.size() << std::endl;
}
出力
3
2
2
0
イテレート中に要素を削除する (C++11)
#include <iostream>
#include <set>
int main()
{
std::set<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 |
指定したキーで要素を探す |
参照
- N2350 Container insert/erase and iterator constness (Revision 1)
- LWG Issue 2258.
a.erase(q1, q2)
unable to directly returnq2
- C++11では、「
a.erase(q1, q2)
の結果としてq2
が返る」という仕様だったが、const_iterator
型が渡された場合にiterator
型を返せない問題があった。そのためC++14では、q2
が指す要素を指すイテレータが返る、ということが明記された
- C++11では、「