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

C++自定义类作为非类型模板参数传入函数的实现方法

自定义类作为非类型模板参数的实现方法

原代码问题

初始实现无法编译,核心原因有3个:

  • 类C的定义位置晚于模板对C类型的引用,编译器解析template<C cc>时还未识别到C的类型定义
  • 传入模板的cc是main函数内定义的运行期局部变量,而非类型模板参数要求实参必须是编译期可确定的常量,这和int示例中直接传入常量100的要求一致
  • C++20标准发布前,语言本身不支持直接将自定义类类型作为非类型模板参数按值传递,仅支持整型、枚举、指针/引用、空指针类型等有限的非类型参数类型。

正确实现

C++20及以上版本(原生支持类类型非类型模板参数)

C++20放宽了非类型模板参数的限制,只要自定义类是字面量类型、满足结构化比较要求(简单的公有成员聚合类默认满足),就可以直接像int一样作为非类型模板参数使用,写法和预期效果完全一致:

#include <iostream>
using namespace std;

// 类定义必须放在模板声明之前
class C
{
public:
    int l = 10;
};

// 直接声明类类型的非类型模板参数
template<C cc> void A()
{
    cout << cc.l << endl;
}

int main()
{
    // 直接传入编译期构造的常量对象,和传入int常量写法一致
    A<C{100}>();
    // 也可以先定义constexpr编译期常量后传入
    constexpr C cc{200};
    A<cc>();
}

C++11/14/17版本(兼容实现)

旧标准不支持类类型按值作为非类型模板参数,可以通过传递静态存储期constexpr实例的const引用实现近似效果:

#include <iostream>
using namespace std;

class C
{
public:
    int l = 10;
};

// 提前定义静态存储期的编译期常量实例
constexpr C c_val1{100};
constexpr C c_val2{200};

// 以const引用作为非类型模板参数类型
template<const C& cc> void A()
{
    cout << cc.l << endl;
}

int main()
{
    A<c_val1>();
    A<c_val2>();
}

注意事项

  • 所有非类型模板参数的实参都必须是编译期可确定的常量,无论参数是int还是自定义类类型,都不能传入运行期才会初始化的局部变量
  • C++20按值传递类类型参数时,传入的临时对象要求是编译期可构造的constexpr值,类不能包含运行期才会执行的构造逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 11:27:13