std::remove() #2

std::remove() で algorithm ヘッダの std::remove() が便利、と書いたんだけど、落とし穴があった。

std::remove() は要素を削除するというよりは、要素を削除してそれ以降をシフトする、という感じ。

std::vector<int> v;
v.push_back(0);
v.push_back(1);
v.push_back(2);
std::remove(v.begin(), v.end(), 0);
std::remove(v.begin(), v.end(), 1);
printf("%d", v.size());

上記のコードで出力されるのは 3 だ。

std::remove() はサイズを変更しないのだ。

じゃあどうすればいいか。

std::vector<int> v;
v.push_back(0);
v.push_back(1);
v.push_back(2);
v.erase(std::remove(v.begin(), v.end(), 0), v.end());
v.erase(std::remove(v.begin(), v.end(), 1), v.end());
printf("%d", v.size());

結局 std::vector::erase() を使わなきゃならない。

これはイディオムらしく、以下に説明がある。

More C++ Idioms/消去・削除(Erase-Remove)

なるほどねー。