skip to content
Mehdi Mehdikhani
Table of Contents

C-style arrays always felt clunky to me. std::array is C++11’s answer - all the performance of regular arrays but with STL container benefits.

What std::array Actually Is

It’s basically a thin wrapper around a regular C array, but with size information and STL methods:

std::array<int, 5> arr = {1, 2, 3, 4, 5};
// Instead of: int arr[5] = {1, 2, 3, 4, 5};
std::cout << arr.size() << std::endl; // 5 - knows its size!

The size is part of the type, so std::array<int, 5> is completely different from std::array<int, 10>.

Why I Use It

  1. Size is always available: No more passing size separately or losing track of array bounds:
void processArray(const std::array<int, 100>& arr) {
for (size_t i = 0; i < arr.size(); ++i) { // No magic numbers
// process arr[i]
}
}
  1. Works with STL algorithms: All the range-based goodness:
std::array<int, 5> numbers = {5, 2, 8, 1, 9};
std::sort(numbers.begin(), numbers.end());
auto it = std::find(numbers.begin(), numbers.end(), 8);
  1. Bounds checking in debug: at() throws if you go out of bounds:
std::array<int, 3> arr = {1, 2, 3};
// arr[10]; // Undefined behavior
// arr.at(10); // Throws std::out_of_range

When I Actually Use std::array

Most of the time, I reach for std::array when:

  1. Fixed-size collections: When I know the exact size at compile time:
std::array<std::string, 12> months = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
  1. Mathematical operations: For vectors, matrices, coordinates:
using Vec3 = std::array<double, 3>;
Vec3 position = {1.0, 2.0, 3.0};
Vec3 velocity = {0.1, 0.2, 0.3};
// Can use range-based for
for (auto& component : position) {
component *= 2.0;
}
  1. Replacing C arrays in APIs: When interfacing with C code:
// Old way
void legacy_function(int data[10]);
int buffer[10];
legacy_function(buffer);
// New way
std::array<int, 10> buffer{};
legacy_function(buffer.data()); // .data() gives raw pointer

The Gotchas

The size being part of the type can be annoying:

void process(std::array<int, 5>& arr); // Only works with size 5
// void process(std::array<int, 10>& arr); // Need separate function

For this reason, I often use templates or std::span (C++20) when I need to work with different sizes.

Performance

Zero overhead compared to C arrays. The compiler optimizes away the wrapper completely. Same memory layout, same performance, but with type safety and STL benefits.

std::array lives on the stack, so it’s perfect for small, fixed-size collections. For dynamic sizes, std::vector is still the way to go.