You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 03:47:35