すいません、勉強不足でした

先日書いたエントリについて、id:cxxさんにより、間違えている部分など、丁寧に修正すべき点を教えていただけているエントリが上げていただきました。

ありがとうございます!
勉強不足で、正しいと思い込んだをアップしてしまうのは問題ですが、修正していただけると、本人はとても勉強になり、ありがたく思います。(間違えた内容を信じてしまった方々にはとても迷惑な話ですが、)現在作業環境が一人なもので、こうして直接知らない方々からご教授いただけるというのはネットのすばらしさの一つですね。
それでは、修正していただけている点を復習してみます。

remove_ifの比較関数は普通の関数でも良い

std::unary_function というテンプレートクラスを継承したクラスに operator() というオペレータ関数を定義して、その関数オブジェクト(?)を作れるようにする必要があります。

そんなことはありません。std::list::remove_ifに渡す関数オブジェクトは以下のような単純なもので問題ありません。これはstd::remove_if等のSTLアルゴリズムでも同様です。std::unary_functionの継承は関数アダプタ(std::bind1st等)に関数オブジェクトを組み合わせる可能性のある場合にのみ必要です。(MSDNのサンプルは関数オブジェクトクラスの模範的な定義を示しているのでしょう)

なるほど普通の関数でも良いのですね。サンプルを鵜呑みにしていました。
以下のようなコードでも大丈夫とのこと。

bool is_even(int n) { return n % 2 == 0; }
nums.remove_if(is_even);

実は、sort関数の比較関数は簡単なのになー、と思っていたのです(参考)。もうちょっと調べていたら分かることでしたね。
「remove_ifの比較関数は普通の関数ポインタでもOK」、了解です!

ちなみにεπιστημη氏の上記エントリでは、find_ifの使い方が描かれていますが、これもremove_ifと渡すべき関数オブジェクトは同じですね。
そして、、なるほど!これはきれい!ようやく特定のクラス(や構造体)を作って、それをオブジェクトとして渡す意味が理解できました。

const char* names[] = {
  "中", "えムナウ", "επιστημη", "けろ",
  "とりこびと", "とっちゃん", "夏椰", "なおこ" };
vector<string> wankuma(names, names+8);
vector<string>::iterator found;

// コンストラクタで与えた文字列と一致すればtrue
// を返す operator() を持ったオブジェクト
struct filter {
  string target;
  filter(const string& t) : target(t) {}
  bool operator()(const string& x) const { return x == target; }
};

// filterを与えて検索する
found = find_if(wankuma.begin(), wankuma.end(),
                filter("επιστημη"));
if ( found != wankuma.end() ) cout << "あったー!" << endl;
}

サンプルコード、何を見せるかが腕の見せ所ですね。MSDNとか見てると重要さがわからなくなってきますから。

std::remove_ifの挙動について

std::remove_ifはpredが真を返す要素を飛ばしながら元の範囲を上書きしているだけで、削除対象の要素を範囲の末尾に移動させているわけではありません。

そうでしたか。これもちょっとした確認コードで確認しました。
きっと後ろに移動しているであろう、という希望でもありました。後ろに回すことにより、ユーザによるフレキシブルな後処理対応を可能にしているのだと思い込んでいました。
「std::remove_ifで返ってくるイテレータ以降の値は不定」、了解です!

STLでは前置インクリメントを使用すべし

最後のは全く知りませんでした。

イテレータを次の要素に進める場合には特別な理由がない限り、後置インクリメント(it++)ではなく常に前置インクリメント(++it)を使用すべきです。イテレータオーバーロードする後置インクリメント演算子は生のポインタと同様に、インクリメント演算子が適用される前の値を返す必要があるため、戻り値として返すためのイテレータのコピーが発生します(std::vectorは例外)。

Effective STLとかには載ってるのでしょうか。やっぱり時間を見つけてSTLをきちんと勉強したほうがよさそうですね。
でも、見栄えの問題というか、意味の問題からあまり好きではないのでなかなか慣れそうにないのですが、今度から気にしてみます。
「後置インクリメントより前置インクリメント」、了解です!

それでは、元記事のほうにも注釈を入れておきます。