はじめに
C++のコンテナ(vector
, list
, map
など)を操作する上で、「特定の要素を削除する」という処理は非常に頻繁に発生します。C++には、この削除処理を行うための様々な方法が用意されており、状況に応じて最適なものを選択することが重要です。
この記事では、コンテナから要素を削除するための主要なテクニックを、以下のカテゴリに分けて網羅的に解説します。
- 先頭/末尾の要素を削除
- 指定した位置の要素を削除
- 条件に一致する要素を削除
map
やset
からキーを指定して削除
1. 先頭/末尾の要素を削除する (pop_front
, pop_back
)
list
や deque
のような、先頭や末尾への要素の追加・削除が高速に行えるコンテナでは、専用のメンバ関数が用意されています。
サンプルコード
#include <iostream>
#include <list>
using namespace std;
int main() {
list<int> numbers = {10, 20, 30, 40};
// 先頭要素を削除
numbers.pop_front(); // -> {20, 30, 40}
// 末尾要素を削除
numbers.pop_back(); // -> {20, 30}
for(int n : numbers) {
cout << n << " ";
}
cout << endl;
return 0;
}
注意: std::vector
には .pop_front()
はありません。
2. 指定した位置の要素を削除する (.erase
)
イテレータを使って、コンテナ内の特定の位置にある要素、または特定の範囲の要素を削除します。
サンプルコード
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> numbers = {10, 20, 30, 40, 50};
// 2番目の要素(30)を削除
// .begin()は先頭を指すイテレータ
numbers.erase(numbers.begin() + 2); // -> {10, 20, 40, 50}
for(int n : numbers) {
cout << n << " ";
}
cout << endl;
return 0;
}
3. 条件に一致する要素を削除する
「偶数の要素を全て削除する」といった、特定の条件を満たす要素をまとめて削除するには、主に2つの方法があります。
方法A: Erase-Remove イディオム (C++17まで)
<algorithm>
の std::remove_if
と、コンテナの .erase()
を組み合わせる、伝統的な方法です。 remove_if
は、削除すべきでない要素をコンテナの前方に詰め、実際に削除されるべき要素範囲の開始イテレータを返します。その後、.erase()
でその範囲を物理的に削除します。
// ...
vector<int> data = {1, 2, 3, 4, 5, 6};
// remove_ifで偶数をコンテナの後方に移動させ、その開始地点を取得
auto first_to_erase = remove_if(data.begin(), data.end(), [](int n){ return n % 2 == 0; });
// その開始地点から末尾までをeraseで物理的に削除
data.erase(first_to_erase, data.end());
// data は {1, 3, 5} になる
方法B: std::erase_if
(C++20以降)
C++20では、Erase-Removeイディオムの冗長さを解消する、よりシンプルで安全な std::erase_if
が導入されました。
完成コード
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<int> numbers = {1, 2, 3, 4, 5, 6, 7, 8};
// C++20の erase_if を使って、奇数の要素を全て削除
erase_if(numbers, [](int n){ return n % 2 != 0; });
for(int n : numbers) {
cout << n << " ";
}
cout << endl;
return 0;
}
解説: erase_if(コンテナ, 条件)
という一行だけで、条件に一致する全ての要素が安全かつ効率的に削除されます。
4. map
やset
からキーを指定して削除する
std::map
やstd::set
のような連想コンテナでは、キーを指定して .erase()
を呼び出すことで、対応する要素を削除できます。
サンプルコード
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {
map<string, int> stock = {{"りんご", 5}, {"みかん", 8}, {"ぶどう", 3}};
// キー "みかん" を持つ要素を削除
stock.erase("みかん");
for(const auto& [key, value] : stock) {
cout << key << ": " << value << "個" << endl;
}
return 0;
}
まとめ
今回は、C++のコンテナから要素を削除する様々な方法を解説しました。
目的 | 主な方法 |
先頭/末尾の削除 | .pop_front() / .pop_back() |
位置を指定して削除 | .erase(イテレータ) |
条件に合う要素を削除 | std::erase_if (C++20) / Erase-Removeイディオム |
キーを指定して削除 | .erase(キー) |
状況に応じて最適な削除方法を選択することが、効率的で読みやすいコードを書くための鍵となります。特に、条件に基づく削除では、C++20以降の環境であれば、std::erase_if
を使うのが最もシンプルで安全です。