boost::mem_fnでハマった

コールバック関数のインスタンスメソッドを使いたい、ってのはよくあることだと思う。

その方法として、boost::mem_fnをよく使っている。

コールバック関数のUserParamに、インスタンスのポインタをvoid**にキャストして登録、
コールバック関数では、それをインスタンスのポインタにキャストして利用・・・ってのは嫌いなので。

コードはこんな感じになる。

class Foo
{
public:
  void Bar( int n )
  {
    std::cout << "Bar: " << n++ << std::endl;
  }
};

Foo foo;
boost::bind( boost::mem_fn( &Foo::Bar), &foo, _1 )

今日はこういうコードを書いてはまった。

Foo foo;
boost::bind( boost::mem_fn( &Foo::Bar), foo, _1 )

&fooじゃなくて、fooとしてしまったのだ。
そうすると、インスタンスのコピーができてしまい、変な動作になっていた。

ちなみに私はコールバックホルダ的なクラスを作るとき、
IXxxへのポインタとかを登録せず、関数ポインタを登録させることが多い。
IXxxの方が正当だと思うけど、いちいちIXxxから派生させることが面倒なこともあるので、
あえてこうしている。

誰かメリットとデメリットと教えてください。