类模板实参推导指南使用Abbreviated function template语法的编译器合规性问题
使用缩写函数模板语法的类模板推导指南合规性问题
我尝试使用缩写函数模板(Abbreviated function template)语法编写用户自定义类模板参数推导指南,代码可在GCC和Clang编译通过,但在MSVC中报错,错误信息为:
error C3539: a template-argument cannot be a type that contains 'auto'
请问哪款编译器的行为符合C++标准?
示例代码:
template <typename Type, int Count> struct Array { Type data[Count]; Array (auto ... arg) { int count = 0; ((data[count++] = arg),...); } }; // 缩写函数模板语法 - MSVC编译失败 Array (auto first, auto ... next) -> Array<decltype(first), 1 + sizeof...(next)>; // 常规语法 // template <typename Type, typename ... Args> Array (Type first, Args ... next) -> Array<Type, 1 + sizeof...(Args)>; int main () { Array a(1,2,3); }
结论
GCC和Clang的行为符合C++20及后续标准,MSVC的报错不符合标准要求。
原因解析
C++20标准明确允许在类模板推导指南中使用缩写函数模板语法:
- 缩写函数模板(如
Array (auto first, auto ... next))会被标准隐式转换为带模板参数的函数模板形式,等价于template<typename T, typename... Args> Array(T first, Args... next)。 - 推导指南的目标模板参数
Array<decltype(first), 1 + sizeof...(next)>是合法的:decltype(first)会推导为first的具体类型,1 + sizeof...(next)是编译期可确定的常量表达式,两者都不包含auto类型。
MSVC错误提示中提到的“模板参数不能包含auto”是对标准的误解——此处的auto是缩写函数模板的参数占位符,并非直接作为类模板的参数传递,推导后的最终模板参数是具体类型和常量,不存在包含auto的情况。
兼容写法
如果需要兼容MSVC,可以使用代码中注释的常规模板语法编写推导指南,两种写法在标准中语义完全等价。
内容的提问来源于stack exchange,提问作者Petwoip
相关产品推荐
相关产品推荐

