Cのコールバック関数をC++のメンバ関数にバインディングする方法
たとえば libevent のような C 言語でかかれたイベント駆動型のライブラリを C++ から使っていると、C++ のメンバ関数をコールバックとしてセットできたらうれしいことが多いですよね。以下のようにすればできます。
たとえば、コールバック関数をセットする関数の型が、
void set_foo_callback(void (*)(void* cb_arg), void* cb_arg);
なら、以下のようにクラスとメンバ関数を引数にとるテンプレート関数を定義し、
template <typename T, void (T::*FUNC)()> void to_foo_callback(void* cb_arg) { T* obj = reinterpret_cast<T*>(cb_arg); (obj->*FUNC)(); }
以下のように受け渡せばいい。
class K { public: K() { set_foo_callback(to_foo_callback<K, &K::on_foo>, this); } protected: void on_foo() { ... } };
メンバ関数を呼び出すラッパー関数をいちいち書かなくていいのでうれしい。
前世紀の GCC だと関数ポインタをテンプレート引数に渡せなかったと思うんですが、最近はできるんですね。