std::array是零开销、类型安全的原生数组替代品,支持size()、范围for、拷贝赋值及编译期长度计算;原生数组无size()、不可赋值、传参退化为指针、长度无法泛化使用。

std::array 有 size() 方法,原生数组没有
原生数组 T arr[N] 在传递给函数时会退化为指针,丢失长度信息,sizeof(arr)/sizeof(arr[0]) 只在定义作用域内有效;而 std::array 是类型完整的类模板,自带 size() 成员函数,且支持范围 for 循环:
std::arraya = {1, 2, 3}; for (int x : a) { /* OK */ } // 自动推导范围 int b[3] = {1, 2, 3}; for (int x : b) { / OK,但仅当b未退化时 / } // 若传入 void f(int x[]),则 x 是 int*,无法用范围 for
常见错误:对函数参数中的原生数组调用 size() 或 begin() —— 编译失败,因为那只是个指针。
std::array 支持拷贝和赋值,原生数组不支持
原生数组不能直接赋值(int a[3], b[3]; a = b; 非法),也不能作为函数返回值(除非包装成结构体);std::array 默认提供深拷贝语义,可安全传值、返回、放入容器:
-
std::array拷贝是逐元素复制,开销与原生数组 memcpy 相当,但语法自然 - 可直接作为
std::vector的元素:std::vector<:array>>合法;而std::vector编译不过 - 返回局部
std::array不触发额外拷贝(C++17 guaranteed copy elision),性能无损
std::array 的类型包含长度,原生数组类型也含长度但不可泛化
两者类型都含尺寸信息(int[5] 和 std::array 都是不同类型的实例),但关键差异在于模板参数的可操作性:
立即学习“C++免费学习笔记(深入)”;
-
std::array的N是非类型模板参数,可在编译期参与计算、SFINAE、constexpr 判断 - 原生数组长度无法在模板中直接提取(
std::extent_v可查,但不能用于推导新类型) - 例如:写一个只接受偶数长度
std::array的函数,可用enable_if_t;对原生数组几乎无法做等效约束
std::array 不带来运行时开销,但要求编译期确定大小
二者底层内存布局完全一致(连续、无额外字段),std::array 零成本抽象;但它的尺寸必须是常量表达式,无法替代变长数组(VLA)或运行时决定大小的场景:
- 不能写
std::array(n 是变量)—— 编译错误 - 若大小仅在运行时可知,必须改用
std::vector或手动new[] - 某些嵌入式环境禁用 STL 时,
std::array可能因依赖和分配器设施被规避,而原生数组始终可用
真正容易忽略的是:把 std::array 当作“更安全的原生数组”很自然,但它无法解决“大小不确定”这个根本限制——这时候不是该换写法,而是该换容器。











