GCC 14中auto模板参数推导失效,哪款编译器符合C++标准?
GCC 14与旧版GCC/Clang的模板参数推导差异:符合标准的是哪方?
以下C++代码可在GCC 13及更早版本、所有Clang版本正常编译,但GCC 14会拒绝编译。只需采用以下两种修改方式之一,即可让GCC 14接受该代码:
- 将
B的模板参数类型unsigned char改为int - 将
foo的模板参数auto改为int
#include <iostream> template <int T> struct A { int value = T; }; // Replacing 'unsigned char' with 'int' makes it work with GCC 14: template <unsigned char X> using B = A<X>; // Or, replacing 'auto' with 'int' makes it work with GCC 14: template <auto X> void foo(B<X>& mat) noexcept { std::cout << mat.value << "\n"; } int main() { A<2> mat; foo(mat); }
GCC 14给出的错误信息如下:
<source>: In function 'int main()': <source>:18:8: error: no matching function for call to 'foo(A<2>&)' 18 | foo(mat); | ~~~^~~~~ <source>:10:6: note: candidate: 'template<auto X> void foo(B<((unsigned char)X)>&)' 10 | void foo(B<X>& mat) noexcept | ^~~ <source>:10:6: note: template argument deduction/substitution failed: <source>:18:8: note: couldn't deduce template parameter 'X' 18 | foo(mat); | ~~~^~~~~
结论:GCC 14的行为符合C++标准
原因如下:
- 模板别名
B的非类型模板参数类型是unsigned char,foo的模板参数X为auto,推导时X的类型必须与B的参数类型严格一致(即unsigned char)。 - 调用
foo(mat)时,mat是A<2>类型,其模板参数是int类型的2。要匹配B<X>(等价于A<X>,X为unsigned char),需要X(unsigned char)隐式转换为int后等于2,但C++标准规定,模板参数推导过程中,非类型模板参数的推导要求精确类型匹配,不允许通过隐式反向推导来确定X的类型和值。 - 旧版GCC和Clang的行为属于非标准的宽松处理,GCC 14修复了这一问题,严格遵循了C++标准中模板参数推导的规则。
内容的提问来源于stack exchange,提问作者Pavel Kirienko
相关产品推荐
相关产品推荐

