This question already has an answer here:
C++ Notes: Array Initialization has a nice list over initialization of arrays. I have a
int array[100] = {-1};
expecting it to be full with -1's but its not, only first value is and the rest are 0's mixed with random values.
The code
int array[100] = {0};
works just fine and sets each element to 0.
What am I missing here.. Can't one initialize it if the value isn't zero ?
2: Is the default initialization (as above ) faster than the usual loop through the whole array and assign a value or does it do the same thing?
The page you linked states
Speed issue: Any differences would be negligible for arrays this small. If you work with large arrays and speed is much more important than size, you can have a const array of the default values (initialized at compile time) and then
memcpy
them to the modifiable array.1) When you use an initializer, for a struct or an array like that, the unspecified values are essentially default constructed. In the case of a primitive type like ints, that means they will be zeroed. Note that this applies recursively: you could have an array of structs containing arrays and if you specify just the first field of the first struct, then all the rest will be initialized with zeros and default constructors.
2) The compiler will probably generate initializer code that is at least as good as you could do by hand. I tend to prefer to let the compiler do the initialization for me, when possible.
With {} you assign the elements as they are declared; the rest is initialized with 0.
If there is no
= {}
to initalize, the content is undefined.Another way of initializing the array to a common value, would be to actually generate the list of elements in a series of defines:
Initializing an array to a common value can easily be done:
Note: DUPx introduced to enable macro substitution in parameters to DUP
In C++, it is also possible to use meta programming and variadic templates. The following post shows how to do it: Programmatically create static arrays at compile time in C++.
Using
std::array
, we can do this in a fairly straightforward way in C++14. It is possible to do in C++11 only, but slightly more complicated.Our interface is a compile-time size and a default value.
The third function is mainly for convenience, so the user does not have to construct a
std::integral_constant<std::size_t, size>
themselves, as that is a pretty wordy construction. The real work is done by one of the first two functions.The first overload is pretty straightforward: It constructs a
std::array
of size 0. There is no copying necessary, we just construct it.The second overload is a little trickier. It forwards along the value it got as the source, and it also constructs an instance of
make_index_sequence
and just calls some other implementation function. What does that function look like?This constructs the first size - 1 arguments by copying the value we passed in. Here, we use our variadic parameter pack indexes just as something to expand. There are size - 1 entries in that pack (as we specified in the construction of
make_index_sequence
), and they have values of 0, 1, 2, 3, ..., size - 2. However, we do not care about the values (so we cast it to void, to silence any compiler warnings). Parameter pack expansion expands out our code to something like this (assuming size == 4):We use those parentheses to ensure that the variadic pack expansion
...
expands what we want, and also to ensure we are using the comma operator. Without the parentheses, it would look like we are passing a bunch of arguments to our array initialization, but really, we are evaluating the index, casting it to void, ignoring that void result, and then returning value, which is copied into the array.The final argument, the one we call
std::forward
on, is a minor optimization. If someone passes in a temporary std::string and says "make an array of 5 of these", we would like to have 4 copies and 1 move, instead of 5 copies. Thestd::forward
ensures that we do this.The full code, including headers and some unit tests: