c++ - 可变参数函数和可变参数模板重载查找
问题描述
我有一个带有 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(...)
。
推荐阅读
- sql-server - SQL Server 中的“void”类型是什么?
- python - 如何使用 Python 根据部分值将字典拆分为多个字典
- javascript - 我有一个包含多个对象的数组。我们可以根据条件创建新对象吗?
- moodle - 无法检索外部页面的用户 ID(moodle)
- azure - Azure Bot 返回“加载资源失败:服务器响应状态为 502(错误网关)”错误
- visual-studio - Visual Studio 2017 告诉我现在每次打开 IDE 时都可以使用 Visual Studio 2019 版本
- vba - 使用 VBA PowerPoint 引用幻灯片的字幕以进行格式化
- python - lib/pythonX.Y/no-global-site-packages.txt 的路径
- go - Go 包函数中的模拟函数
- android - 验证者 GSON 类型适配器