Section

std::array

std::array is a fixed-size contiguous container that stores its elements directly inside the object.

It gives built-in arrays a standard container interface without changing the core tradeoff: the size is part of the type and never changes at runtime.

# Declarations

template< class T, std::size_t N >
struct array;

(since C++11)

# Template parameters

  • T: element type. The exact requirements depend on the operations used. In general, elements must be move-constructible and move-assignable for operations such as assignment and swap.
  • N: number of elements in the array; 0 is allowed

# Semantic model

  • array<T, N> owns exactly N elements and never reallocates.
  • Elements are stored contiguously, so data() can be passed to APIs that expect a pointer to an array.
  • Unlike a built-in array, std::array does not decay to T* automatically.
  • Unlike built-in arrays, std::array is assignable, swappable, tuple-like, and works directly with standard container algorithms.
  • Unlike std::vector, the size is fixed for the lifetime of the object.
  • std::array meets the usual container requirements with two notable exceptions: a default-constructed array is not empty, and swap has linear complexity.
  • For N == 0, begin() == end() and that iterator value is unique for the zero-sized array object; calling front or back is undefined behavior.

# Example

#include <algorithm>
#include <array>
#include <iostream>
#include <iterator>
#include <string>
 
int main()
{
    std::array<int, 3> a1{{1, 2, 3}};
    std::array<int, 3> a2 = {1, 2, 3};
 
    std::sort(a1.begin(), a1.end());
    std::ranges::reverse_copy(a2, std::ostream_iterator<int>(std::cout, " "));
    std::cout << '\n';
 
    std::array<std::string, 2> a3{"E", "\u018E"};
    for (const auto& s : a3)
        std::cout << s << ' ';
    std::cout << '\n';
}

This is the usual array pattern: stack-friendly fixed-size storage with the ergonomics of a standard container.

# Member types

Member typeDefinition
value_typeT
size_typestd::size_t
difference_typestd::ptrdiff_t
referencevalue_type&
const_referenceconst value_type&
pointervalue_type*
const_pointerconst value_type*
iteratorcontiguous iterator to value_type
const_iteratorcontiguous iterator to const value_type
reverse_iteratorstd::reverse_iterator<iterator>
const_reverse_iteratorstd::reverse_iterator<const_iterator>

# Iterator invalidation

std::array never reallocates, so iterators and references remain valid for the lifetime of the array object itself. Operations such as swap change element values, not the underlying storage identity.

A notable edge case is swap: iterators still refer to the same positions in the same array objects after the call, but the values observed through them may have changed because the elements were swapped.

# Reference map

AreaKey entries
Implicit special membersaggregate construction, implicit destructor, implicit copy/move assignment
Element accessat, operator[], front, back, data
Iteratorsbegin, cbegin, end, cend, rbegin, crbegin, rend, crend
Capacityempty, size, max_size
Operationsfill, swap
Non-member functionscomparison operators, get, std::swap(std::array), to_array
Helper classestuple_size<std::array>, tuple_element<std::array>
Related surfacededuction guides

# Deduction guides

The class has deduction guides so direct construction such as std::array a{1, 2, 3}; can infer both the element type and the array bound.

# Notes

std::array is an aggregate, so initialization follows aggregate-initialization rules. That matters especially for default initialization versus value initialization, and for historical C++11 brace quirks.

Because the size is part of the type, std::array<int, 3> and std::array<int, 4> are different and unrelated types.

# See also