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 typedef
s, 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}
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.