我最近学习了参数包,然后我编写了下面的程序,它用msvc编译,但不用clang和gcc.Live demo:
#include <array>
template<typename T, std::size_t... rows> int func(T (&arr...)[rows])
{
return 5;
}
int main()
{
int arr[2][3][4];
auto a = func(arr);
}
从上面的演示中可以看出,msvc编译了它,但是gcc说:
<source>:3:56: error: 'arr' was not declared in this scope
3 | template<typename T, std::size_t... rows> int func(T (&arr...)[rows])
| ^~~
<source>:3:69: error: parameter packs not expanded with '...':
3 | template<typename T, std::size_t... rows> int func(T (&arr...)[rows])
| ^
<source>:3:69: note: 'rows'
<source>:6:2: error: expected ';' before 'int'
6 | }
| ^
| ;
7 | int main()
| ~~~
Compiler returned: 1
我想知道哪个编译器是正确的以及原因。
2条答案
按热度按时间mrfwxfqh1#
参数包的语法在 * 声明符id之前有
...
*:这对于更简单的参数包是相同的:
空格并不重要,
Ts... arr
是一种更常见的样式,但不能很好地反映...
是声明符...arr
的一部分,而不是类型说明符Ts
的一部分。MSVC似乎因为某种原因接受了在声明符id
arr
之后使用...
的语法,但这应该是格式错误的。然而,MSVC确实按照正确的顺序给予了它相同的含义,见下文。但是它并不具有您想要的含义,即.
T (&...arr)[rows]
扩展为T (&arr1)[rows1], T (&arr2)[rows2], T (&arr3)[rows3]
等形式的参数列表。您不能使用包扩展将[rowsN]
语法添加到参数类型。在调用
auto a = func(arr);
时,T
将是int[3][4]
,并且rows
将具有值为2
的单个元素。omhiaaxx2#
该程序格式错误,因为在引入函数参数包时,扩展模板参数包的省略号
...
必须出现在函数参数名之前或代替函数参数名。换句话说,
...
应该放在函数参数名b
之前,这样,修正后的程序看起来就像: