可变参数函数和可变参数模板重载查找

尼基塔·拉里奥诺夫(Nikita Larionov)

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

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

有人可以解释查询的工作方式吗?在我看来,每个函数的目的是相同的(除了第一个是c ++样式,第二个是c样式)。当我使用带有参数的函数调用函数时,尽管它们的类型不同,f(5, "hello")或者f(5, 10)它始终是可变参数模板(第一次重载),但是当我调用不带参数的函数时,f()它始终是可变参数函数(第二次重载)。哪个编译器遵循正确的规则来选择正确的函数,其背后的逻辑是什么?

生锈的

是的,在C ++中有许多与此相关的规则。

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

然后,如果列表具有多个候选者,则执行重载解析

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

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

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

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

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

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

如果f()我们得到

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

模棱两可,但第一个是模板,因此选择了非模板f(...)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章