首页 > 解决方案 > 可变参数函数和可变参数模板重载查找

问题描述

我有一个带有 2 个重载参数的函数

template<typename... Args>
void f(Args&&...) {
    cout << "Args..." << endl;
}
 
void f(...) {
    cout << "..." << endl;
}

有人可以解释一下查找是如何工作的吗?在我看来,每个函数的目的都是一样的(除了第一个是 c++ 风格,第二个是 c 风格)。当我调用带有参数的函数时,尽管它们的类型f(5, "hello")f(5, 10)它总是可变参数模板(第一次重载),但是当我调用不带参数的函数时,f()它总是可变参数函数(第二次重载)。编译器是否有严格的规则来选择正确的函数,其背后的逻辑是什么?

标签: c++

解决方案


是的,在 C++ 中有很多规则。

当编译器遇到类似的调用时f(5, 10),首先合成一个可行的候选列表,这涉及函数模板的实例化(这涉及模板参数的推导)。

然后,如果列表有多个候选者,则执行重载决策。

一些关键的超载排名规则是:

  • 始终首选更好的匹配(隐式转换最少的匹配)。

    • 标准转换优于用户定义的转换,后者优于省略号。
  • 当没有更好的匹配时,首选非模板版本。

所以如果f(5, 10)我们得到

  • f<int,int>(int,int)- 需要 0 次转化,
  • f(...)- 需要 2 个省略号“转换”。

第一个需要较少的转换,所以它赢了。

如果f()我们得到

  • f<>()- 需要 0 次转化,
  • f(...)- 需要 0 次转换。

有歧义,但第一个是模板,所以选择了非模板f(...)


推荐阅读