c++编译器如何决定调用这些函数中的哪个

How does the C++ compiler decide which of these functions is called?

本文关键字:函数 调用 编译器 何决定 决定 c++      更新时间:2023-10-16

考虑以下设置:

我得到一个接口

template<class T>
  void FooClass<T>::foo(boost::function<double (int)> f)
{...}

我想用函子实现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);

使用第二个定义,而我希望它调用第一个定义——这可以改变吗?

编译器'首选'第二个定义,因为模板版本导致与函数对象形参精确匹配,而boost::function形参需要隐式转换被接受(隐式转换在直接重载解析之后被认为是)。您可以通过构造一个boost::function对象,然后将传递给函数来实现您想要的功能(注意,您可以在同一行中执行此操作,为了清晰起见,我只是单独执行):

boost::function<double (int)> bMyFun(myFunInstance);
fooClassInstance.foo(bMyFun);

你可以显式地构造一个boost::function对象,这样第一个重载将被优先考虑:

fooclass.foo(boost::function<double (int)>(f));

关于你的问题标题,你想知道重载解析是如何工作的吗?当选择重载时,非模板化类型比模板化类型更适合匹配,但是直接匹配的模板化类型(FunPtr = MyFun)比隐式转换(MyFun -> boost::function<double(int)>)更适合匹配,因此在原始情况下,第二个重载匹配得更好。

(感谢@David指出了我最初表述中的一个明显错误!)