C++ std::array
/ 2 min read
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
- 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] }}- 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);- 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_rangeWhen I Actually Use std::array
Most of the time, I reach for std::array when:
- 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"};- 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 forfor (auto& component : position) { component *= 2.0;}- Replacing C arrays in APIs: When interfacing with C code:
// Old wayvoid legacy_function(int data[10]);int buffer[10];legacy_function(buffer);
// New waystd::array<int, 10> buffer{};legacy_function(buffer.data()); // .data() gives raw pointerThe 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 functionFor 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.