考虑以下设置:
我获得了一个界面
template<class T>
void FooClass<T>::foo(boost::function<double (int)> f)
{...}
我想使用Functor实现f:
class MyFun {
public: double operator()(int a) {do something...;}
}
然而,界面
中定义了另一个功能template<class T>
template <class FunPtr>
void FooClass<T>::foo(const FunPtr& f)
{...}
调用FooClass对象时,
MyFun f;
FooClass<double> fooclass;
fooclass.foo(f);
它使用第二个定义,而我希望它调用第一个定义 - 可以以某种方式更改吗?
答案 0 :(得分:6)
编译器'preferres'第二个定义,因为模板版本导致函数对象参数的精确匹配,而{ {1}}参数需要 隐式转换才能被接受(隐式转换在直接重载解析后被视为)。你可以通过构建一个boost::function
对象来实现你想要的,然后然后将它传递给函数(注意你可以在同一行中执行此操作,我只是单独执行它为清楚起见):
boost::function
答案 1 :(得分:2)
您可以显式构造boost::function
对象,以便首选重载:
fooclass.foo(boost::function<double (int)>(f));
关于你的问题标题,你想知道重载解析是如何工作的吗?当选择重载时,untemplated类型比模板化类型更好匹配,但直接匹配(FunPtr = MyFun
)的模板化类型比implictit转换(MyFun -> boost::function<double(int)>
)更好匹配,所以第二次重载在原始情况下匹配得更好。
(感谢@David在我的原始配方中指出了一个明显的错误!)