std::array::size() 是编译期 constexpr 函数,直接返回模板参数指定的固定大小,类型为 std::size_t,不可变且无需运行时计算。

std::array 的 size() 成员函数直接返回编译期确定的大小
std::array 是 C++11 引入的固定大小容器,它的 size() 成员函数在编译期就能求值,返回的是模板参数中指定的元素个数,不是运行时计算的结果。它和 C 风格数组的 sizeof(arr)/sizeof(arr[0]) 语义一致,但更安全、更清晰。
常见错误是误以为要调用 std::size()(C++17 起的非成员函数)或试图对 std::array 取地址再用 sizeof——没必要,也容易出错。
-
size()返回类型是std::size_t,不是int,注意类型匹配(尤其在比较或循环中) - 不能对
std::array对象本身调用sizeof来“验证”大小:因为std::array可能有填充字节,sizeof(arr)≠arr.size() * sizeof(T)(虽然通常相等,但不保证) - 模板参数大小必须是编译期常量,所以
std::array<int n></int>中的n不能是变量
std::array<double> arr = {1.1, 2.2, 3.3};
std::cout <h3>为什么不能用 .data() + sizeof 或 std::size(arr)?</h3>
<p>有人习惯对原始指针用 <code>sizeof</code>,但 <code>arr.data()</code> 返回的是 <code>T*</code>,<code>sizeof(arr.data())</code> 永远是指针大小(如 8),毫无意义;而 <code>std::size(arr)</code> 虽然在 C++17+ 可用,但它内部就是调用 <code>arr.size()</code>,多一层间接,且需要包含 <code><iterator></iterator></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>
<ul>
<li>直接用 <code>arr.size()</code> 最直白、最高效,无额外开销</li>
<li>
<code>std::size()</code> 主要为统一 C 风格数组、<code>std::array</code>、<code>std::vector</code> 等提供泛型接口,对单个 <code>std::array</code> 实例没必要绕路</li>
<li>如果误写成 <code>sizeof(arr.data())</code>,会得到 4 或 8,而不是元素个数,极易引发越界访问</li>
</ul>
<h3>size() 在 constexpr 上下文中的使用限制</h3>
<p><code>std::array::size()</code> 是 <code>constexpr</code> 函数,但能否用于需要常量表达式的场景(比如模板非类型参数、数组维度),取决于编译器和标准版本。C++17 起基本可靠,但要注意对象必须是字面类型且定义在 constexpr 作用域内。</p>
<ul>
<li>以下合法:<code>constexpr std::array<int> a = {1,2,3}; constexpr int N = a.size();</int></code>
</li>
<li>以下非法:<code>std::array<int> a; constexpr int N = a.size();</int></code>(<code>a</code> 不是 constexpr 对象)</li>
<li>若用于模板参数,如 <code>template<int n> void f(); f<a.size>();</a.size></int></code>,需确保 <code>a</code> 是 constexpr 对象且编译器支持 C++17 折叠</li>
</ul>
<h3>和 std::vector::size() 的关键区别别搞混</h3>
<p><code>std::vector::size()</code> 返回运行时实际元素个数,可能小于容量(<code>capacity()</code>);而 <code>std::array::size()</code> 永远等于容量,且不可变。把两者当作同一类接口使用,容易在逻辑上误判“可扩容性”。</p>
<ul>
<li>不要用 <code>arr.resize(n)</code> —— <code>std::array</code> 根本没有 <code>resize()</code> 成员</li>
<li>不要假设 <code>arr.size()</code> 会随 push_back 类操作变化 —— 它根本不能 push_back</li>
<li>传参时若函数签名是 <code>void f(const std::array<t n>&)</t></code>,<code>N</code> 必须完全匹配,无法像 <code>std::vector</code> 那样接受任意大小</li>
</ul>
<p>有些人在调试时打印 <code>arr.size()</code> 却看到意外值,往往是因为用了未初始化的局部 <code>std::array</code> 并误读了内存;真正的问题不在 <code>size()</code>,而在对象生命周期或初始化方式。</p></double>C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










