繁体   English   中英

MSVC 与 Clang/GCC 错误在函数模板的重载解决期间,其中一个包含参数包

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM