参数包在MSVC可编译,GCC/Clang报错,哪个编译器合规?
参数包语法的编译器差异:谁的行为符合标准?
结论:GCC和Clang的行为是符合C++标准的,MSVC能够编译是因为它支持了一个非标准的语法扩展。
问题根源:错误的参数包声明语法
你的函数模板参数声明T (&arr...)[rows]违反了C++标准的语法规则:
- 在C++中,声明函数参数包时,展开标记
...必须直接修饰参数包的名称。正确的参数包语法应该是T (&...arr)[rows](表示一组引用参数,每个参数都是指向T[rows_i]类型数组的引用)。你把...放在参数名arr和数组括号[rows]之间的写法,是标准不允许的。 - 同时,模板参数
rows是一个参数包,在函数参数列表中需要和参数包一起展开,但你的错误语法导致编译器无法识别这种关联,因此GCC和Clang会抛出“参数包未展开”的错误。
为什么MSVC能编译?
MSVC实现了一个非标准的语法扩展,允许这种不符合标准的参数包写法。这属于编译器的私有扩展,并不被C++标准所认可,因此其他遵循标准的编译器(如GCC、Clang)会拒绝编译该代码。
如果你想实现“接收任意维度的多维数组”
如果你的需求是让函数能处理任意维度的多维数组,正确的实现方式可以用递归模板:
#include <cstddef> // 基础版本:处理非数组类型(递归终止) template<typename T> int func(T&) { return 5; } // 递归版本:处理数组类型,逐层拆解维度 template<typename T, std::size_t N> int func(T (&arr)[N]) { return func(arr[0]); } int main() { int arr[2][3][4]; auto a = func(arr); }
如果你想接收多个数组参数
如果你的需求是接收多个不同大小的数组作为参数,正确的参数包写法如下:
#include <cstddef> template<typename T, std::size_t... rows> int func(T (&...arr)[rows]) { return 5; } int main() { int arr1[2], arr2[3], arr3[4]; auto a = func(arr1, arr2, arr3); }
内容的提问来源于stack exchange,提问作者user20562802
相关产品推荐
相关产品推荐

