Wiki
std::array
1.What problem does this section solve?
C-style arrays (int arr[5] ) have many drawbacks: they cannot be directly assigned, they decay to pointers when passed to functions, losing size information, and they lack bounds checking. While std::vector is powerful, it uses dynamically allocated memory and incurs a slight overhead.
std::arrayWhat it solves is: when you need anarray with a size determined at compile time and allocated on the stackit provides a safe array that is as fast as a C array but has the STL container interface (it has size(), has iterators, and is assignable).
2.What is this feature?
std::array<T, N> is a container template in the STL that encapsulates a fixed-size array. Its size is determined at compile time, it does not dynamically allocate memory (it is on the stack), and it wraps a C array while providing the standard interface of an STL container.
3.C++ Standard Edition
C++11
4.Required header files
#include <array>
Run result: This code block does not contain the main function; it is a syntax, interface, or multi-file example and cannot be run independently, so there is no terminal output.
5.Basic syntax
std::array<元素类型, 大小> 变量名; // 默认初始化(值未定义)
std::array<元素类型, 大小> 变量名 = {}; // 全部初始化为零
std::array<元素类型, 大小> 变量名 = {v1, v2, ...}; // 列表初始化
Run result: This code block does not contain the main function; it is a syntax, interface, or multi-file example and cannot be run independently, so there is no terminal output.
6.Common Usage
| Operation | Description |
|---|---|
a[i] |
Random access (no bounds checking) |
a.at(i) |
Random access (with bounds checking) |
a.size() |
Returns the number of elements (compile-time constant) |
a.empty() |
Whether it is empty (always false) |
a.front() |
Returns the first element |
a.back() |
Returns the last element |
a.fill(val) |
Fills all elements with val |
a.data() |
Returns a pointer to the underlying C array |
7.Example code
7.1.Example 1: Creating an array and accessing elements
#include <iostream>
#include <array>
using namespace std;
int main()
{
// 创建一个包含 5 个 int 的 array,并初始化
std::array<int, 5> arr = {10, 20, 30, 40, 50};
// 用下标访问
std::cout << "arr[0] = " << arr[0] << "\n";
std::cout << "arr[4] = " << arr[4] << "\n";
// 用 size() 获取大小
std::cout << "size = " << arr.size() << "\n";
return 0;
}
Running result:
arr[0] = 10
arr[4] = 50
size = 5
7.2.Example 2: Building on Example 1, use at() for safe access and fill() for filling
#include <iostream>
#include <array>
using namespace std;
int main()
{
std::array<int, 5> arr = {10, 20, 30, 40, 50};
// 用 at() 安全访问
std::cout << "arr.at(2) = " << arr.at(2) << "\n";
// 用 fill() 将所有元素设为同一个值
arr.fill(99);
std::cout << "after fill: ";
for (int n : arr)
{
std::cout << n << " ";
}
std::cout << "\n";
return 0;
}
Running result:
arr.at(2) = 30
after fill: 99 99 99 99 99
7.3.Example 3: Based on Example 2, compare passing parameters for C arrays and std::array
#include <iostream>
#include <array>
using namespace std;
// C 风格:数组退化为指针,丢失大小信息
void print_c_array(int* arr, int size)
{
std::cout << "C array: ";
for (int i = 0; i < size; ++i)
{
std::cout << arr[i] << " ";
}
std::cout << "\n";
}
// std::array:大小信息不丢失
void print_std_array(const std::array<int, 5>& arr)
{
std::cout << "std::array: ";
for (int n : arr)
{
std::cout << n << " ";
}
std::cout << "\n";
std::cout << "size from inside function = " << arr.size() << "\n";
}
int main()
{
std::array<int, 5> arr = {1, 2, 3, 4, 5};
// C 风格:需要额外传大小
print_c_array(arr.data(), arr.size());
// std::array:自带大小信息
print_std_array(arr);
return 0;
}
Running result:
C array: 1 2 3 4 5
std::array: 1 2 3 4 5
size from inside function = 5
8.Operation result
See the "run results" for each example above.
9.Key syntax explanation in the example
| Example | What was discussed | Newly introduced syntax | Why it is written this way | Notes |
|---|---|---|---|---|
| Example 1 | Creating an array and basic access | std::array<T, N>、size() |
The array size is a compile-time constant,size() returns a fixed value |
The size must be a compile-time constant; you cannot pass a variable |
| Example 2 | Safe access with at() and filling with fill() | at()、fill() |
at()An out-of-bounds access throws an exception;fill() convenient for batch assignment |
fill()Assigns the same value to all elements |
| Example 3 | Comparing C arrays and array parameter passing | data()、const std::array<int,5>& |
When an array is passed as a parameter, size information is not lost | The array size is part of the type; different sizes are different types |
10.When is the difference between array and vector obvious?
If you are just storing 5 integers,array and vector both seem usable. But in engineering, the difference mainly lies in "whether the size is fixed" and "whether dynamic expansion is needed":
| Scenario | Recommendation | Reason |
|---|---|---|
Three-axis IMU data {x, y, z} |
std::array<double, 3> |
The size is always 3, no expansion needed |
Fixed-length PID parameters {kp, ki, kd} |
std::array<double, 3> |
The size is known at compile time, and the semantics are clear |
| Read a batch of sensor points at runtime | std::vector<Point> |
The number of points is only known at runtime |
| The user enters an arbitrary amount of data | std::vector<T> |
Need push_back dynamic growth |
array More like a "fixed array with an STL interface,"vector More like a "variable-length array." Don't use it everywhere just because array is more lightweight: whenever the number of elements is only known at runtime, you should use vector.
10.1.Example 4: Fixed three-axis data is more suitable for an array
#include <array>
#include <iostream>
using namespace std;
// std::array 是固定长度数组,长度在编译期就确定。
double norm3(const std::array<double, 3>& v)
{
return v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
}
int main()
{
// 程序从 main 函数开始执行,下面的语句会按顺序运行。
std::array<double, 3> accel = {0.1, 0.2, 9.8};
std::cout << "accel size = " << accel.size() << "\n";
std::cout << "squared norm = " << norm3(accel) << "\n";
return 0;
}
Running result:
accel size = 3
squared norm = 96.09
In this example, the three-axis data must be exactly 3 values. Use std::array<double, 3> to encode this constraint into the type; if you mistakenly pass std::array<double, 2>, a compile-time error will occur.
11.Common Errors
Error 1: Using a variable to specify the array size
int n = 5;
std::array<int, n> arr; // ❌ 编译错误!n 必须是编译期常量
Run result: This code block does not contain the main function; it is a syntax, interface, or multi-file example and cannot be run independently, so there is no terminal output.
Correct approach: use the constexpr constant, or switch to std::vector.
Error 2: Accessing without initialization
std::array<int, 5> arr; // 值未定义(栈上的垃圾值)
std::cout << arr[0]; // ❌ 未定义行为
Run result: This code block does not contain the main function; it is a syntax, interface, or multi-file example and cannot be run independently, so there is no terminal output.
Correct approach: use {} to initialize or fill().
Error 3: Assigning arrays of different sizes to each other
std::array<int, 3> a = {1, 2, 3};
std::array<int, 5> b = a; // ❌ 编译错误!类型不同
Run result: This code block does not contain the main function; it is a syntax, interface, or multi-file example and cannot be run independently, so there is no terminal output.
Correct approach:std::array<int,3> and std::array<int,5> are different types and cannot be assigned to each other.
12.Usage Recommendations
- For compile-time known sizes, use arrayIf the size is known at compile time, using
std::arrayis lighter thanstd::vector(no heap allocation). - Replacing C arrays: wherever
std::arraycan be used, don't useint arr[N]. - Note the size when passing parametersThe size of
std::array<T, N>is part of the type; the function signature must specify N. - AssignableUnlike C arrays,
std::arraycan be assigned as a whole using=(of the same type).
13.Summary
std::array<T, N>Encapsulates a fixed-size array whose size is determined at compile time.- Has the standard interface of STL containers (
size(),at(), iterators, etc.). - Can be assigned as a whole, and does not decay to a pointer when passed to a function, so size information is not lost.
- Suitable for scenarios where the size is known at compile time, and is more lightweight than
vector.