[英]GCC & Clang vs MSVC Bug while expanding template parameter pack in the same parameter clause for function templates
[英]MSVC vs Clang/GCC bug during overload resolution of function templates one of which contains a parameter pack
当我注意到一个这样的案例(如下所示)在 gcc 和 clang 中编译良好但在 msvc 中编译时,我正在使用参数包:
template<class T> void func(T a, T b= T{})
{
}
template<class T, class... S> void func(T a, S... b)
{
}
int main()
{
func(1); // Should this call succeed?
}
这是验证相同的链接: https ://godbolt.org/z/8KsrcnMez
可以看出,上面的程序在 msvc 中失败并显示错误消息:
<source>(13): error C2668: 'func': ambiguous call to overloaded function
<source>(6): note: could be 'void func<int,>(T)'
with
[
T=int
]
<source>(2): note: or 'void func<int>(T,T)'
with
[
T=int
]
<source>(13): note: while trying to match the argument list '(int)'
但是使用 gcc 和 clang 也可以很好地编译。
哪个编译器在这里?
MSVC 拒绝代码是正确的。 根据temp.func.order#5.example-2调用func(1)
是模棱两可的。 标准中给出的例子如下:
注意:由于在调用上下文中,这种类型推导只考虑具有显式调用参数的参数,因此忽略某些参数(即函数参数包、具有默认参数的参数和省略号参数) 。
template<class T > void g(T, T = T()); // #3 template<class T, class... U> void g(T, U ...); // #4 void h() { g(42); // error: ambiguous }
这意味着在所讨论的示例中,调用func(1)
也是模棱两可的。
请注意, cppreference在下面给出的示例中有勘误表:
template<class T> void g(T, T = T()); // #1 template<class T, class... U> void g(T, U...); // #2 void h() { g(42); // calls #1 due to the tie-breaker between parameter pack and omitted parameter }
从上面的例子可以看出,cpprefernce 错误地表示应该选择第一个重载#1
。
这已在我最近进行的编辑中得到修复。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.