std::array传参不退化,大小是类型一部分,支持安全访问、赋值比较、标准算法和编译期约束,零开销但需避免裸指针操作。

std::array 传参时不会退化为指针
普通数组作为函数参数时,类型信息会丢失,int arr[10] 实际等价于 int* arr,sizeof(arr) 返回指针大小,arr.size() 根本不存在。这导致泛型代码难写、模板推导失败、安全检查失效。
std::array 是完整类型,std::array<int></int> 的大小和维度是类型的一部分:
void f(const std::array<int>& a) {
std::cout <ul>
<li>模板函数中可直接用 <code>decltype(a)::size()</code> 或 <code>a.size()</code> 获取长度</li>
<li>重载或特化时能按不同尺寸区分(如 <code>std::array<t></t></code> 和 <code>std::array<t></t></code> 是两个不同类型)</li>
<li>避免手动传 <code>size_t n</code> 参数,减少出错可能</li>
</ul>
<h3>std::array 支持标准算法和范围 for 循环</h3>
<p>普通数组要配合 <code>std::sort</code>,得写 <code>std::sort(std::begin(arr), std::end(arr))</code>,还得确保传对长度;而 <code>std::array</code> 直接用成员函数:</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill4025" title="C++ 算法竞赛自动化测试数据生成与校验框架"><img
src="https://img.php.cn/upload/skill/000/000/081/178988956499722.jpg" alt="C++ 算法竞赛自动化测试数据生成与校验框架" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill4025" title="C++ 算法竞赛自动化测试数据生成与校验框架" class="overflowclass">C++ 算法竞赛自动化测试数据生成与校验框架</a>
<p class="overflowclass">根据原题生成新题面、验证器及完整测试数据,自动套用 testlib 模板,用于用户要求生成测试数据时。</p>
</div>
<a rel="nofollow" href="/xiazai/skill4025" title="C++ 算法竞赛自动化测试数据生成与校验框架" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
<pre class="brush:php;toolbar:false;">std::array<int> a = {5, 2, 8, 1, 9};
std::sort(a.begin(), a.end()); // ✅ 干净利落
for (int x : a) { /* ✅ 自然支持 range-for */ }</int>
-
begin()/end()是成员函数,无需依赖 ADL 或辅助函数 -
at()提供带异常的边界检查(operator[]不检查,行为同原生数组) -
front()/back()安全访问首尾元素,空数组调用未定义,但至少语义明确
std::array 可整体赋值、比较、返回
普通数组不能直接赋值:int a[3], b[3]; a = b; 编译报错;== 比较也非法。而 std::array 支持全部这些操作:
std::array<int> a = {1,2,3}, b = {4,5,6};
a = b; // ✅ 赋值合法
if (a == b) { ... } // ✅ 按元素逐个比较
auto get() { return a; } // ✅ 可安全返回,不退化、不悬垂</int>
- 返回
std::array不涉及堆分配,栈上拷贝开销极小(尤其小尺寸) - 结构体中含
std::array成员时,自动获得默认赋值/比较语义 - 注意:大尺寸(如
std::array<char></char>)拷贝仍存在成本,需权衡
std::array 的初始化和编译期约束
普通数组允许部分初始化、聚合初始化宽松;std::array 要求显式尺寸且初始化方式更严格:
int c_arr[5] = {1}; // ✅ 剩余为 0
std::array<int> a = {1}; // ✅ 同样补零(C++14 起支持)
std::array<int> b{1}; // ✅ 统一初始化,推荐
std::array<int> c = {1,2,3,4,5,6}; // ❌ 编译错误:太多初始值</int></int></int>
- 尺寸必须是字面量常量表达式,无法用变量(
int n = 5; std::array<int n></int>❌) - 不支持运行时决定大小——这是设计取舍,不是缺陷;需要动态大小请用
std::vector - 若需从运行时数据构造,先确认尺寸再声明,或封装成工厂函数
真正容易被忽略的是:std::array 的“零开销抽象”只在你信任它的类型系统时成立。一旦混用 reinterpret_cast 或裸指针操作,边界安全和类型优势就立刻归零。它不是万能胶,而是给定尺寸场景下更清晰、更少出错的工具。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










