C ++编译器如何决定调用哪些函数?

时间:2011-08-18 09:41:59

标签: c++ templates functor

考虑以下设置:

我获得了一个界面

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);

它使用第二个定义,而我希望它调用第一个定义 - 可以以某种方式更改吗?

2 个答案:

答案 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在我的原始配方中指出了一个明显的错误!)