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

推导类型能否作非类型模板实参?StringLiteral省略N的原因

C++模板相关问题解答

1. 推导类型能否用作非类型模板形参的类型?

在C20及更高版本中,推导类型(比如auto或带约束的推导类型)可以用作非类型模板形参的类型,但有个关键前提:推导出来的实际类型必须属于C标准允许的非类型模板形参合法类型集合。

合法类型包括:整数类型、枚举类型、指针、引用、std::nullptr_t,以及C++20新增的字面类(满足特定constexpr要求的类)等。比如:

// 合法:auto推导N为int,属于合法非类型形参类型
template<auto N>
struct NumHolder {
    static constexpr auto value = N;
};

// 调用时推导N的类型为int
NumHolder<42> nh;

如果推导出来的类型不合法(比如std::string这类非字面类型),编译器会直接报错,因为这类类型无法作为非类型模板形参。

2. 为何声明template<StringLiteral lit>时可省略StringLiteral的size_t N模板参数?

这是C++20的类模板实参推导(CTAD)和字面类作为非类型模板形参两个特性结合的结果:

  1. 字面类资格:代码中的StringLiteral是一个字面类——它拥有constexpr构造函数,成员value是字面类型的数组,完全符合C++20对非类型模板形参的字面类要求,因此可以直接作为非类型模板形参的类型。
  2. 自动推导模板参数:当你传入字符串字面量(比如Print<"test">())时,编译器会用这个字符串字面量(类型为const char[5])触发类模板实参推导,自动算出StringLiteral的模板参数N为5,实例化出StringLiteral<5>的对象,再把这个对象作为非类型模板形参传给Print模板。

简单说,编译器会帮你完成N的推导工作,不需要显式写出template<StringLiteral<N> lit>。


内容的提问来源于stack exchange,提问作者Petr

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 18:32:40