c++ 参数包在msvc中有效,但在gcc和clang中无效

smdnsysy  于 2023-03-14  发布在  其他
关注(0)|答案(2)|浏览(130)

我最近学习了参数包,然后我编写了下面的程序,它用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

我想知道哪个编译器是正确的以及原因。

mrfwxfqh

mrfwxfqh1#

参数包的语法在 * 声明符id之前有... *:

template<typename T, std::size_t... rows> int func(T (&...arr)[rows])    
{
   return 5;  
}

这对于更简单的参数包是相同的:

template<typename... Ts>
void test(Ts ...arr);

空格并不重要,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的单个元素。

omhiaaxx

omhiaaxx2#

该程序格式错误,因为在引入函数参数包时,扩展模板参数包的省略号...必须出现在函数参数名之前或代替函数参数名。
换句话说,...应该放在函数参数名b之前,这样,修正后的程序看起来就像:

//-----------------------------------------------------vvv------------>prior to function parameter name 
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);
    
}

相关问题