私はこの答えに少し遅れていますが、問題はバインディングであるため、コールバック登録関数のテンプレート化されたバージョンと通常の関数ポインターの別のバージョンを使用して、後でこの手順を実行できます。
template<typename C>
void RegisterCallback(void (C::* func)(int, bool), C* inst)
{
MyCallback callback(boost::bind(func, inst, _1,_2));
}
void RegisterCallback(void (*func)(int, bool))
{
MyCallback callback(func);
}
A * myA = new A();
RegisterCallback(&A::GoodCallback, myA);
RegisterCallback(&A::BadCallback, myA); // DOES NOT COMPILE
RegisterCallback(GoodCallback);
RegisterCallback(BadCallback); // DOES NOT COMPILE
これは VS2010 で期待どおりに機能しますが、メンバー関数と非メンバー関数を正しく処理するために 1 つではなく 2 つのコールバック登録関数が必要になるという欠点があります。
別のオプションとして、boost function_types ライブラリを参照することもできます。関数ポインターのパラメーターの型を抽出し、それらを MPL シーケンスとして返す parameter_types メタ関数を提供します。次に、ちょっとしたテンプレート マジックを使用して、次のようなコールバック関数のパラメーターを検証できます。
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/function_types/parameter_types.hpp>
#include <boost/mpl/equal.hpp>
using namespace boost;
using namespace boost::function_types;
template< typename Function >
void RegisterCallback(Function f)
{
BOOST_MPL_ASSERT((
mpl::equal<
parameter_types< Function >,
parameter_types< void(int,bool) >
>
));
MyCallback callback(f);
}
template<typename Function, typename T>
void RegisterCallback(Function f, T* inst)
{
BOOST_MPL_ASSERT((
mpl::equal<
parameter_types< Function >,
parameter_types< void (T::*)(int,bool) >
>
));
MyCallback callback(boost::bind(f, inst, _1, _2));
}
これは VS2010 でも期待どおりに機能しますが、2 つの関数宣言が必要ですが、それらを構造体内で定義する (そして T の既定のテンプレート パラメーター引数を使用する) 場合は 1 つにまとめることができるはずです。