根本原因是模板参数类型与实参语义不匹配:若模板声明为typename t,则必须传类型(如int);若声明为int n,则必须传编译期常量值(如42)。std::array合法因其第二参数为非类型模板参数,而template struct x{}中x非法,因42是值而非类型。

为什么 template 实参传 int 却报 “type/value mismatch”?
根本原因:编译器把本该当值(value)传入的地方,误判成要传类型(type)。常见于模板参数声明为 typename 或 class,但你却传了 int、nullptr 这类非类型;或者反过来,模板声明为非类型参数(如 int N),却传了 std::vector<int></int> 这种类型。
典型错误代码:
template<typename t>
struct A { };
A a; // 错!42 是值,T 声明为 typename,期望类型</typename>
解决思路不是“改写法”,而是“对齐语义”——看模板定义怎么声明的,就按什么规则传。
std::array 为什么能写 std::array<int></int> 而我的模板不行?
因为 std::array 的第二个参数是 std::size_t N,属于非类型模板参数(NTTP),允许传字面量整数。你的模板若没这么声明,就无法接受 5 这样的值。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 想传类型(如
int、MyClass):模板参数必须用typename T或class T - 想传值(如
5、true、nullptr):参数必须显式声明为非类型,例如int N、bool B、auto V(C++17 起支持auto推导 NTTP) - C++20 起还可传 constexpr 对象,但需满足字面类型且有内部链接
遇到 type/value mismatch 怎么快速定位和修复?
别猜,直接看报错行附近的模板定义和实例化两处:
- 查模板声明:找到对应位置的参数,确认它是
typename还是int这类非类型 - 查实例化调用:看传进去的是变量名、字面量,还是类型名(如
int、decltype(x)) - 检查是否用了
typename修饰依赖名称(比如在模板内写T::value_type,漏掉typename可能导致解析歧义,间接引发此错) - 注意 C++17 以前不支持浮点数或类类型作为 NTTP,传
3.14或std::string必错
示例修复:
template<typename t> struct X {}; // 期望类型
X<int> x1; // ✅
X x2; // ❌ 报 type/value mismatch
template<int n> struct Y {}; // 期望值
Y y1; // ✅
Y<int> y2; // ❌ 同样报错</int></int></int></typename>
用 auto 模板参数时为什么还报错?
C++17 引入 template<auto v></auto> 看似万能,但它只接受编译期可确定的常量表达式,且推导出的类型必须匹配实参。传一个运行时变量、非常量表达式,或类型不一致(比如模板推导为 const int&,你传了 long),依然会触发 type/value mismatch。
- 确保实参是
constexpr或字面量(如5、"hello") - 避免传函数名(未取地址)、临时对象(除非是字面类型)
- 注意字符串字面量类型是
const char[N],不是std::string
最容易被忽略的是:模板参数推导不跨转换,哪怕 int 到 long 是隐式转换,template<auto></auto> 也不自动适配——必须类型严格一致。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










