removeの注意点

Effective STL
第9項 消去オプションは注意して選択しよう

連続メモリコンテナContainerがある

Container<int> c;

このコンテナに含まれている100という値を全て取り除きたい場合、
eraseとremoveを用いる。
慣用的には以下のような記述がある。

c.erase( remove( c.begin() , c.end() , 100 ) , c.end() );


・・・らしい。
removeなんてあったのか。
どういう動作をするのか知らないが、
ぱっと見、removeは特定の値を削除する関数に見える。
なので、何故eraseが出てくるのか分からん。


第32項 本当に削除したい場合は、remove風アルゴリズムの後にeraseを使おう

vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(100);
v.push_back(100);
v.push_back(4);
v.push_back(5);
v.push_back(100);
v.push_back(6);

vector<int>::iterator new_end_it = remove( v.begin() , v.end() , 100 );

cout << "全部" << endl;
copy( v.begin() , v.end() , ostream_iterator<int>( cout , "\n" ) );

cout << "v.begin() からnew_end_itまで" << endl;
copy( v.begin() , new_end_it , ostream_iterator<int>( cout , "\n" ) );
    
cout << "new_end_itからv.end()まで" << endl;
copy( new_end_it , v.end() , ostream_iterator<int>( cout , "\n" ) );


結果

size:9
全部
1
2
3
4
5
6
5
100
6
v.begin() からnew_end_itまで
1
2
3
4
5
6
new_end_itからv.end()まで
5
100
6


なんだこれ罠だろ。
この項が言うに、
removeにはイテレータしか渡してないわけだから、
コンテナのeraseメンバ関数を呼び出すのは不可能。
だからこんな事になっているらしい。ひぃぃ。