Search

6.15 — An introduction to std::array

In previous lessons, we’ve talked at length about fixed and dynamic arrays. Although both are built right into the C++ language, they both have downsides: Fixed arrays decay into pointers, losing the array length information when they do, and dynamic arrays have messy deallocation issues and are challenging to resize without error.

To address these issues, the C++ standard library includes functionality that makes array management easier, std::array and std::vector. We’ll examine std::array in this lesson, and std::vector in the next.

An introduction to std::array in C++11

Introduced in C++11, std::array provides fixed array functionality that won’t decay when passed into a function. std::array is defined in the array header, inside the std namespace.

Declaring a std::array variable is easy:

Just like the native implementation of fixed arrays, the length of a std::array must be set at compile time.

std::array can be initialized using an initializer lists or uniform initialization:

Unlike built-in fixed arrays, with std::array you can not omit the array length when providing an initializer:

You can also assign values to the array using an initializer list

Accessing array values using the subscript operator works just like you would expect:

Just like built-in fixed arrays, the subscript operator does not do any bounds-checking. If an invalid index is provided, bad things will probably happen.

std::array supports a second form of array element access (the at() function) that does bounds checking:

In the above example, the call to array.at(1) checks to ensure array element 1 is valid, and because it is, it returns a reference to array element 1. We then assign the value of 6 to this. However, the call to array.at(9) fails because array element 9 is out of bounds for the array. Instead of returning a reference, the at() function throws an error that terminates the program (note: It’s actually throwing an exception of type std::out_of_range -- we cover exceptions in chapter 15). Because it does bounds checking, at() is slower (but safer) than operator[].

std::array will clean up after itself when it goes out of scope, so there’s no need to do any kind of cleanup.

Size and sorting

The size() function can be used to retrieve the length of the array:

This prints:

length: 5

Because std::array doesn’t decay to a pointer when passed to a function, the size() function will work even if you call it from within a function:

This also prints:

length: 5

Note that the standard library uses the term “size” to mean the array length — do not get this confused with the results of sizeof() on a native fixed array, which returns the actual size of the array in memory (the size of an element multiplied by the array length). Yes, this nomenclature is inconsistent.

Also note that we passed std::array by (const) reference. This is to prevent the compiler from making a copy of the array when the array was passed to the function (for performance reasons).

Rule: Always pass std::array by reference or const reference

Because the length is always known, for-each (ranged for) loops work with std::array:

You can sort std::array using std::sort, which lives in the algorithm header:

This prints:

1 3 5 7 9

The sorting function uses iterators, which is a concept we haven’t covered yet, so for now you can treat the parameters to std::sort() as a bit of magic. We’ll explain them in the lesson on iterators.

Summary

std::array is a great replacement for build-in fixed arrays. It’s efficient, in that it doesn’t use any more memory than built-in fixed arrays. The only real downside of a std::array over a built-in fixed array is a slightly more awkward syntax, and that you have to explicitly specify the array length (the compiler won’t calculate it for you from the initializer). But those are minor quibbles — we recommend using std::array over built-in fixed arrays for any non-trivial use.

6.16 -- An introduction to std::vector
Index
6.14 -- Pointers to pointers

81 comments to 6.15 — An introduction to std::array

  • Taksh

    Hey Alex,

    You wrote:

    In the for each loop you defined &element as const. Then how it is able to change its value on every iteration ?

    Thanks in advance.

    • Alex

      The element is created and initialized with each loop iteration, and destroyed at the end of each loop iteration. It is essentially a local variable to the loop.

  • umang

    int main()
    {
      std::array<int,5> myarray{1,2,3,4,5};
      int *ptr=myarray;
      std::cout<<*(ptr+2);

      return 0;
    }
    why is this incorrect?

    • Alex

      myarray is a std::array, and std::array doesn’t have a conversion to int*. This means you can’t assign an integer pointer to point at it.

  • lnm

    Can you tell me what algorithm does std::sort use ?

  • Omri

    Indeed I was thinking in terms of functions.Thank you for clarifying this.

  • Omri

    Hello Alex,
    Thank you for the reply.
    As I understood matters up to here, we #include header (.h ) files only, and these include function declarations, and do not include function definitions/implementations (which, when up to us, we place in .cpp files). This is good enough for correct compilation of single files.
    For linkage it is up to the linker to find the function definition/implementation when the code calls/uses the declared functions. The linker uses its "magic" search capabilities to find the definition of the function in .cpp files residing in the folder "housing" the calling file, or elswhere in what is somewhat vaguely refered to as "system files". All this, if correct, is difficult to accurately go along with "…std::array is defined in the array header, inside the std namespace".
    Thank you Again.

    • Alex

      Your understanding is good, but incomplete. You’re focused on functions here, but std::array is not a function -- it’s a type. And types play by different rules.

      Generally, it’s not enough to declare a type in a header -- with a few exceptions, types are more often defined in headers, and then included into whatever files need them. So the std::array type is defined in the array header.

Leave a Comment

Put C++ code inside [code][/code] tags to use the syntax highlighter