不用std::array而自实现是为了控制内存布局、避免标准库依赖或练手理解栈上数组封装;核心需用模板参数t和n、private原生数组存储、默认/拷贝构造、operator[]不检查边界而at()检查并抛异常、注意size_t越界陷阱、constexpr/noexcept修饰及data()双版本返回。

为什么不用 std::array 而要自己写?
因为想控制内存布局、避免依赖标准库(比如嵌入式环境),或单纯练手理解栈上数组的封装逻辑。自己实现能看清 operator[] 边界检查、size() 返回值类型、拷贝语义这些细节——而 std::array 的很多行为是“黑盒”的。
核心成员和构造函数怎么设计?
模板参数必须是类型 T 和大小 N,内部用 T m_data[N] 原生数组存储,不堆分配。构造函数只提供默认构造(值初始化)和拷贝构造;禁止移动(栈对象不可移动),也不提供迭代器构造——那是 std::vector 的事。
关键点:
-
m_data必须是private,否则破坏封装 - 默认构造要对内置类型做
{}初始化(如int清零),否则值未定义 - 拷贝构造和
operator=必须逐元素赋值,不能memcpy(类类型可能有非平凡构造函数)
operator[] 和 at() 怎么处理越界?
operator[] 不检查边界(和原生数组一致),追求零开销;at() 必须检查并抛出 std::out_of_range。注意:检查逻辑不能写成 if (i >= N),因为 size_t 下标是无符号,负数会回绕——必须用 static_cast<size_t>(i) >= N</size_t> 或直接接受 size_t 类型参数。
示例片段:
constexpr T& at(size_t i) {
if (i >= N) throw std::out_of_range("FixedArray::at: index " + std::to_string(i) + " >= " + std::to_string(N));
return m_data[i];
}
哪些地方容易踩坑?
最容易被忽略的是 constexpr 和 noexcept 修饰——如果所有操作都满足常量表达式条件(比如 N 是字面量,T 是字面量类型),就该加 constexpr;所有不抛异常的函数(如 size()、operator[])应标记 noexcept,否则影响 std::is_nothrow_move_constructible 等特性判断。
另一个坑是 data() 返回指针类型:必须返回 T*(非常量),否则无法支持修改;同时提供 const T* 重载版本,否则 const FixedArray<int></int> 调用 data() 会编译失败。
最后,别忘了 size() 返回 size_t,不是 int——这是和标准容器对齐的基本要求。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











