std::array 是对 C 风格静态数组的封装,保留栈分配、固定大小、零开销特性,但提供容器接口(如 size()、at());声明必须显式指定大小,不支持 CTAD(C++17 起仍不支持),sizeof 等于元素总大小,访问 operator[] 无边界检查,传参应优先用 const 引用以避免拷贝。

std::array 是什么,和普通数组到底差在哪
它不是新类型,而是对 C 风格静态数组的封装:保留栈上分配、固定大小、零开销特性,但补全了容器接口(size()、begin()、at() 等)。编译期就知道长度,不涉及堆分配,也不带运行时额外存储——sizeof(std::array 就等于 5 * sizeof(int)。
声明和初始化必须写明大小,且不能推导
这是最容易卡住的地方。下面这些写法都错:
std::array arr = {1, 2, 3}; // ❌ C++17 起仍不支持 CTAD(类模板实参推导)用于 std::array
std::array<int> a = {1, 2, 3}; // ❌ 缺少第二模板参数(元素个数)
std::array<int> a = {1, 2, 3}; // ✅ 正确</int></int>
想省事?用辅助函数 std::to_array(C++20):
auto a = std::to_array({1, 2, 3}); // 推出 std::array<int></int>
访问元素时,operator[] 不检查边界,at() 才会抛异常
这和 std::vector::operator[] 行为一致,但新手常误以为 std::array 更“安全”。其实:
-
a[5]—— 越界,未定义行为,编译器通常不报错 -
a.at(5)—— 抛出std::out_of_range -
a.front()/a.back()—— 同样不检查空数组(但std::array不可能为空,最小 size 是 0,此时调用front仍是未定义)
传参时别直接传 std::array,优先用引用或指针
因为它是值类型,拷贝代价等于整个数组内存(比如 std::array 拷贝一次就是 8KB)。常见错误写法:
void func(std::array<int> a) { ... } // ❌ 值传递,不必要拷贝</int>
应改为:
-
void func(const std::array—— 最常用& a) -
void func(std::array—— 少用,除非要修改* a) - 泛型场景下用模板:
templatevoid func(const std::array & a)
注意:不能用 std::array 来“泛化大小”,N 必须是编译期常量,每个不同 N 都是独立类型。
真正容易被忽略的是:std::array 的迭代器是原生指针(T*),所以 &a[0] 和 a.data() 等价,能直接传给 C 接口;但它没有 capacity(),也没有 resize()——它就不是用来“变”的,一旦写 std::array,就得接受它的大小钉死在模板参数里。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










