Я немного опоздал с этим ответом, но поскольку проблема заключается в привязке, вы можете сделать этот шаг позже с помощью шаблонной версии для вашей функции регистрации обратного вызова и другой для обычных указателей функций:
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, но имеет недостаток в необходимости не одной, а двух функций регистрации обратного вызова, чтобы правильно работать с функциями-членами и не-членами.
В качестве другого варианта вы можете взглянуть наувеличить библиотеку function_types.Он предоставляет метафункцию parameter_types, которая извлекает типы параметров указателей функций и возвращает их в виде последовательности MPL.Затем, используя немного шаблонного магии, можно проверить параметры функции обратного вызова, например:
#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, но вам все еще нужны два объявления функций, хотя их можно упаковать.они в одном, если вы определяете их внутри структуры (и используете аргумент параметра шаблона по умолчанию для T);