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

当std::array用作非类型模板参数时能否自动推导大小?能否省略SIZE模板参数?

好问题!咱们逐个来拆解你的疑问:

问题1:当std::array用作非类型模板参数时,能否自动推导其大小?

在C17及之后的标准里,完全可以!编译器能够自动推导出std::array的大小模板参数SIZE,前提是你用对了语法——借助C17引入的自动推导非类型模板参数特性。

举个简单的例子:

#include <array>
#include <iostream>

template <auto& Arr>
struct SizePrinter {
    void print() {
        // 直接通过Arr.size()获取大小,不需要手动传SIZE
        std::cout << "Array size: " << Arr.size() << '\n';
    }
};

// 全局的std::array,满足静态存储期要求
std::array<int, 5> my_global_arr{};

int main() {
    SizePrinter<my_global_arr> printer;
    printer.print(); // 输出:Array size: 5
    return 0;
}

这里用auto&作为非类型模板参数,编译器会自动推导Arr的完整类型(包括std::array的元素类型和大小),完全不需要你手动指定SIZE。

问题2:能否省略SIZE模板参数,从array实参推导出来?

当然可以!甚至连T参数都能一起省略。针对你给出的原代码,咱们可以直接改造得更简洁:

方案1:最简写法(直接推导完整array类型)

如果你不需要在类里显式用到T或SIZE,直接用auto&就能搞定:

template <auto& ARR>
class Foo {};

std::array<std::string, 3> str_arr;
Foo<str_arr> foo; // 编译器自动推导ARR是std::array<std::string,3>&,无需指定T和SIZE

方案2:需要用到T或SIZE的场景

如果你需要在类内部使用元素类型T或者大小SIZE,可以通过decltype从传入的ARR中提取:

template <auto& ARR>
class Foo {
public:
    // 提取元素类型
    using ElementType = typename decltype(ARR)::value_type;
    // 提取数组大小,编译期常量
    static constexpr size_t ArraySize = decltype(ARR)::size();

    void show_details() {
        std::cout << "Element type: " << typeid(ElementType).name() 
                  << ", Array size: " << ArraySize << '\n';
    }
};

std::array<double, 4> num_arr;
Foo<num_arr> foo;
foo.show_details(); // 输出类似:Element type: double, Array size: 4

额外注意点

  • 这个特性只支持C17及以上版本,如果你还在使用C11/C++14,那没办法省略SIZE和T,必须显式声明并指定。
  • 作为非类型模板参数的std::array必须是静态存储期的对象(比如全局变量、static局部变量、static成员变量),栈上的普通局部变量无法作为实参传递,会触发编译错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:55:24