可变参数模板和省略号有什么区别?
What is the difference between variadic template and ellipsis?
我知道标题没有多大意义,但代码会解释我的问题。
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 个参数的可变参数模板?
第一个重载到底是什么?
Where syntactically correct and where “...” is not part of
an abstract-declarator, “, ...” is synonymous with “...”.
所以这使得第一个重载成为一个可变参数函数(它也恰好是模板化的)相当于:
template<typename T>
void foo(T, ...) {std::cout << 'A';}
(N.B。cppreference 页面包含一个示例,其中第一个参数和可变参数之间的逗号类似省略。)
为什么我们会看到那个特定的输出?
当您传递两个参数时,编译器更喜欢 other 重载,因为在重载解析期间,在对可行的重载进行排名时,省略号转换序列总是排在最后。 ([over.ics.rank])
当传递单个参数时,编译器更喜欢第一个重载,因为简单地说,省略号不匹配(因为没有任何东西可以匹配)。这可以防止函数被视为省略号转换序列。然后发生正常函数模板排名,并确定此函数比可变函数更专业 ([temp.deduct.partial])
正在关注 overload_resolution#Best_viable_function
对于f(1)
,
我们通过 5)
or, if not that, F1 and F2 are both template specializations and F1 is more specialized according to the partial ordering rules for template specializations
从Function_template_overloading
After considering every P and A in both directions, if, for each type that was considered,
[..]
In case of a tie, if one function template has a trailing parameter pack and the other does not, the one with the omitted parameter is considered to be more specialized than the one with the empty parameter pack.
所以省略函数 template<typename T> void foo(T,...)
被认为比可变函数 template<typename ...Ts> void foo(Ts...)
更专业。
对于f(1, 2)
阅读Ranking_of_implicit_conversion_sequences
在可变版本中我们有精确匹配,而省略号有省略号转换序列
所以可变参数更匹配。
我知道标题没有多大意义,但代码会解释我的问题。
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 个参数的可变参数模板?
第一个重载到底是什么?
Where syntactically correct and where “...” is not part of an abstract-declarator, “, ...” is synonymous with “...”.
所以这使得第一个重载成为一个可变参数函数(它也恰好是模板化的)相当于:
template<typename T>
void foo(T, ...) {std::cout << 'A';}
(N.B。cppreference 页面包含一个示例,其中第一个参数和可变参数之间的逗号类似省略。)
为什么我们会看到那个特定的输出?
当您传递两个参数时,编译器更喜欢 other 重载,因为在重载解析期间,在对可行的重载进行排名时,省略号转换序列总是排在最后。 ([over.ics.rank])
当传递单个参数时,编译器更喜欢第一个重载,因为简单地说,省略号不匹配(因为没有任何东西可以匹配)。这可以防止函数被视为省略号转换序列。然后发生正常函数模板排名,并确定此函数比可变函数更专业 ([temp.deduct.partial])
正在关注 overload_resolution#Best_viable_function
对于
f(1)
,我们通过 5)
or, if not that, F1 and F2 are both template specializations and F1 is more specialized according to the partial ordering rules for template specializations
从Function_template_overloading
After considering every P and A in both directions, if, for each type that was considered, [..]
In case of a tie, if one function template has a trailing parameter pack and the other does not, the one with the omitted parameter is considered to be more specialized than the one with the empty parameter pack.
所以省略函数
template<typename T> void foo(T,...)
被认为比可变函数template<typename ...Ts> void foo(Ts...)
更专业。对于
f(1, 2)
阅读Ranking_of_implicit_conversion_sequences
在可变版本中我们有精确匹配,而省略号有省略号转换序列
所以可变参数更匹配。