use*_*570 5 c++ language-lawyer function-templates pack-expansion 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?
}
Run Code Online (Sandbox Code Playgroud)
这是验证相同内容的链接: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)'
Run Code Online (Sandbox Code Playgroud)
但同样可以用 gcc 和 clang 编译得很好。
这里有哪个编译器?
MSVC 拒绝该代码是正确的。根据temp.func.order#5.example-2该调用func(1)是不明确的。标准中给出的例子如下:
注意:由于在调用上下文中,此类类型推导仅考虑存在显式调用参数的参数,因此会忽略某些参数(即,函数参数包、具有默认参数的参数和省略号参数)。
Run Code Online (Sandbox Code Playgroud)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在下面给出的示例中有勘误表:
Run Code Online (Sandbox Code Playgroud)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应选择第一个重载。
这已在我最近所做的编辑中修复。
| 归档时间: |
|
| 查看次数: |
226 次 |
| 最近记录: |