我对这个答案有点晚了,但是由于问题是绑定,您可以稍后借助回调注册函数的模板版本和常规函数指针的另一个模板版本来执行此步骤:
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 中按预期工作,但缺点是不需要一个而是两个回调注册函数来正确处理成员和非成员函数。
作为另一种选择,您可以查看 boost 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 使用默认模板参数参数),应该可以将它们打包成一个;