Declaring and accessing array elements
An array can be initialized by an initializer list, which is a braced list of values written in the declaration.
Starting an Array with Known Contents
When you create an array, you often already know what its contents should be. Instead of declaring an empty container and then assigning each slot one at a time, you can supply the starting values together with the declaration. This technique is called initializing an array with an initializer list.
Before reading further, look at a declaration and work out three things: what the name refers to, how many values the declaration asks for, and where those values come from. The rest of this article answers each of these questions in turn.
Reading the Parts of a Declaration
The declaration has three parts. The name a1 is the identifier you use to refer to the array later. The type portion array<int, 3> carries two pieces of information: the element type int, and the number 3, which is the number of elements the array is specified to hold. The part after the equals sign, enclosed in braces, is the initializer list, the list of values that fill the array when it is created.
Read the type portion carefully. The 3 in array<int, 3> is the declared size. It is set by the declaration itself, and the braces that follow are checked against it. The values inside the braces are the supplied values.
Mapping Values to Positions
When an initializer list matches the declared size, each value in the braces occupies one slot of the array. The first value sits in the first position, the second in the second, and so on. Counting from zero, the common convention for C++ arrays, the first value goes to position 0, the second to position 1, and the third to position 2. Later code uses these positions to read or change individual elements.
Read the diagram from left to right. The value that appears first in the braces is at the lowest index, and the value that appears last is at the highest index. The position number is always one less than the value's place in the list, because counting starts at zero.
The Size Rule for Initializer Lists
The number of values in an initializer list must be equal to or less than the declared size of the array. Let n be the count of values in the braces and N be the declared size. The rule is written as follows.
Notice that the rule is a comparison, not an exact match. A count equal to the declared size passes, and a smaller count also passes. Only a count that exceeds the declared size breaks the rule. The initializer may match the declared size exactly, or it may supply fewer values. It may never supply more.
Tracing a Valid and an Invalid Declaration
Compare two declarations that both declare an array of size 3. The first supplies three values, which equals the declared size, so it passes. The second supplies four values, which exceeds the declared size, so it breaks the rule.
- The first declaration's count equals the declared size.
- The second declaration's count exceeds the declared size, so the violation is on this declaration line.
In the invalid line, the fourth value has no slot, because the array has only positions 0, 1, and 2. The source material says that when a declaration violates the counting rule, the problem sits in the declaration line, so that is where to look first.
Common Mistakes with Initializer Counts
Common mistake Thinking the brace count must match the declared size exactly
What it looks likestd::array<int, 3> a = {5, 6};Why it failsA smaller count passes the rule. Only a count larger than the declared size breaks it.
Do this insteadCheck whether the count is less than or equal to the declared size, not whether it is identical to it.
Common mistake Reading the declared size from the braces instead of the type
What it looks likestd::array<int, 3> a = {1, 2, 3, 4};Why it failsThe size 3 comes from the type portion array<int, 3>. The braces supply values and do not set the size.
Do this insteadFind N in the type portion, then count the values in the braces and compare them.
Common mistake Looking for the error in later code that uses the array
Why it failsThe source material says that when the counting rule is violated, the problem sits in the declaration line.
Do this insteadStart the search on the declaration line itself.
Predict Before You Check
What do you think happens?
For the declaration std::array<int, 2> p = {7, 8, 9};, does the initializer satisfy the rule, and on which line is any violation found?
Reveal answer
It violates the rule, because 3 values exceed the declared size of 2, and the violation is on this declaration line.
The declared size N is 2 from the type portion, and the count n of values in the braces is 3. Since n is greater than N, the rule n less than or equal to N is broken, and the declaration line is where to look first.
For each declaration, state the declared size N, the count n, and whether n is less than or equal to N. Then identify which declarations are valid: (a) std::array<int, 4> x = {1, 2, 3, 4}; (b) std::array<int, 2> y = {1}; (c) std::array<int, 3> z = {1, 2, 3, 4, 5};
Hints
- The declared size comes from the number inside the type portion, not from the braces.
- Counts equal to N and counts smaller than N both pass.
- Only a count greater than N breaks the rule.
Key Takeaways
- An initializer list is a braced list of values written in an array declaration that fills the array when it is created.
- In a declaration like array<int, 3>, the 3 is the declared size and the braces supply the values.
- The rule is that the number of values in the initializer must be equal to or less than the declared size: equal and smaller counts pass, and only a larger count breaks the rule.
- Values fill positions in order, counting from 0, so the first value goes to index 0.
- When a declaration breaks the counting rule, check the declaration line first.