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

模板参数与构造函数参数的区别及适用场景

两种模板结构体大小指定方式的区别与适用场景

两种实现方式

方式一:构造函数传递参数

template <typename T>
struct Foo {
    int m_size;

    Foo(int u_size)
        :
        m_size {u_size}
    {
    }
};

方式二:非类型模板参数(类似std::array实现)

template <typename T, int u_size>
struct Foo {
    int m_size;

    Foo()
        :
        m_size {u_size}
    {
    }
};

核心区别

  • 大小确定时机:
    • 方式一的m_size是运行时确定的,构造对象时传入的参数决定大小,同一模板实例(比如Foo<int>)的不同对象可以有不同的m_size值。
    • 方式二的u_size是编译时确定的,模板实例化时必须指定常量值,每个不同的u_size会生成独立的模板类型(比如Foo<int, 5>和Foo<int, 10>是完全不同的类型)。
  • 内存与性能:
    • 方式一中m_size是结构体成员变量,每个对象都会额外存储这个整数,占用运行时内存。
    • 方式二中u_size是编译期常量,不需要在对象中存储,结构体内存占用更小;编译器还能基于这个常量做更多优化(比如循环展开、静态数组大小确定等)。
  • 类型一致性:
    • 方式一的同一模板实例下所有对象属于同一类型,比如Foo<int> a(5)和Foo<int> b(10)类型完全相同,可以互相赋值、放在同一个容器里。
    • 方式二中不同u_size对应不同类型,Foo<int,5>和Foo<int,10>无法互相赋值,也不能直接放在同一个容器中(除非用变体或基类指针)。
  • 灵活性:
    • 方式一支持动态大小,运行时可以根据变量、用户输入等调整大小,灵活性更高。
    • 方式二只能使用编译期常量(字面量、constexpr变量),无法在运行时修改大小。

适用场景

方式一适用场景

  • 需要动态调整大小的场景:比如结构体大小要根据运行时数据(用户输入、文件内容)决定。
  • 希望同一模板类型的对象可以统一处理的场景:比如要把不同大小的对象放进同一个std::vector,或者需要统一接口进行赋值、传递。
  • 对运行时性能要求不高,更看重灵活性的场景:比如小型工具类,大小变化频繁且不需要编译期优化。

方式二适用场景

  • 需要编译期确定大小,依赖常量做优化的场景:比如实现固定大小容器(类似std::array),编译器可以对数组操作做极致优化,减少运行时开销。
  • 要求类型安全,不同大小视为不同类型的场景:通过类型系统避免不同大小的对象被错误赋值。
  • 内存敏感的场景:不需要额外存储大小变量,节省每个对象的内存,适合大量创建对象的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 23:15:34