c++ - 可变参数模板和省略号有什么区别?
问题描述
我知道标题没有多大意义,但代码会解释我的问题。
template<typename T>
void foo(T...) {std::cout << 'A';}
template<typename... Ts>
void foo(Ts...) {std::cout << 'B';}
int main(){
foo(1);
foo(1,2);
}
在继续阅读之前尝试猜测该程序的输出:
所以输出是AB
谁能解释为什么对于 1 个参数函数优先考虑省略号,而对于可变参数模板的 2 个参数?
解决方案
第一次重载是什么?
在语法正确且“...”不是抽象声明符的一部分的情况下,“, ...”与“...”同义。
因此,这使得第一个重载成为可变参数函数(也恰好是模板化的),它等效于:
template<typename T>
void foo(T, ...) {std::cout << 'A';}
(注意,cppreference页面包含一个示例,在第一个参数和可变参数之间省略了逗号。)
为什么我们会看到特定的输出?
当您传递两个参数时,编译器更喜欢另一个重载,因为在重载解析期间,在对可行重载进行排序时,省略号转换序列总是排在最后。([over.ics.rank])
当传递单个参数时,编译器更喜欢第一次重载,因为简单地说,省略号不匹配(因为没有什么可以匹配)。这可以防止该函数被视为省略号转换序列。然后发生正常函数模板排名,并确定此函数比可变参数更专业([temp.deduct.partial])
推荐阅读
- tensorflow - 如何在 GCP AI Platform 上使用 TFRecord 文件进行批量预测?
- xaml - Xamarin.Forms XAML 如何在网格中心显示列(不是左绑定)
- java - scala 类的 spark-submit 的反序列化问题
- c# - Moq 何时可以为 Object 抛出 System.ArgumentException?
- reactjs - 笑话测试:当整个反应应用程序在打字稿模块中时如何导入反应组件
- c - 链接器无法从另一个项目中找到库
- c# - WPF ScrollViewer 带有按钮的水平滚动
- nutch - 我想添加存储在段文件夹 nutch 版本 1.17 中的原始内容
- typescript - (ts2339) typescript 中的“TopicMessage”类型不存在属性“token”
- angular - 无法读取未定义的属性“ngModule”