Declaring arrays in C++ Declaring arrays in C++ arrays arrays

Declaring arrays in C++


A std::array<> is just a light wrapper around a C-style array, with some additional nice interface member functions (like begin, end etc) and typedefs, roughly defined as

template<typename T, size_t N>class array{public:    T _arr[N];    T& operator[](size_t);    const T& operator[](size_t) const;    // other member functions and typedefs}

One fundamental difference though is that the former can be passed by value, whereas for the latter you only pass a pointer to its first element or you can pass it by reference, but you cannot copy it into the function (except via a std::copy or manually).

A common mistake is to assume that every time you pass a C-style array to a function you lose its size due to the array decaying to a pointer. This is not always true. If you pass it by reference, you can recover its size, as there is no decay in this case:

#include <iostream>template<typename T, size_t N>void f(T (&arr)[N]) // the type of arr is T(&)[N], not T*{    std::cout << "I'm an array of size " << N;}int main(){    int arr[10];    f(arr); // outputs its size, there is no decay happening}

Live on Coliru


The main difference between these two is an important one.

Besides the nice methods the STL gives you, when passing a std::array to a function, there is no decay. Meaning, when you receive the std::array in the function, it is still a std::array, but when you pass an int[] array to a function, it effectively decays to an int* pointer and the size of the array is lost.

This difference is a major one. Once you lose the array size, the code is now prone to a lot of bugs, as you have to keep track of the array size manually. sizeof() returns the size of a pointer type instead of the number of elements in the array. This forces you to manually keep track of the array size using interfaces like process(int *array, int size). This is an ok solution, but prone to errors.

See the guidelines by Bjarne Stroustroup:

https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Rp-run-time

That can be avoided with a better data type, which std::array is designed for, among many other STL classes.

As a side note, unless there's a strong reason to use a fixed size array, std::vector may be a better choice as a contiguous memory data structure.


std::array and C-style arrays are similar:

  • They both store a contiguous sequence of objects
  • They are both aggregate types and can therefore be initialized using aggregate initialization
  • Their size is known at compile time
  • They do not use dynamic memory allocation

An important advantage of std::array is that it can be passed by value and doesn't implicitly decay to a pointer like a C-style array does.