List of initializers versus vector

In C ++ 11 , one can use initializer lists to initialize parameters in functions. What is his purpose? Could the same thing be done with constant vectors? What is the difference between the two programs below?

Using a list of initializers:

#include <iostream> using namespace std; int sumL(initializer_list<int> l){ int sum = 0; for (const auto i: l){ sum += i; } return sum; } int main(){ cout << sumL({1, 2, 3}) << "\n"; return 0; } 

Using const vector:

 #include <iostream> #include <vector> using namespace std; int sumV(const vector<int> l){ int sum = 0; for (const auto i: l){ sum += i; } return sum; } int main(){ cout << sumV({1, 2, 3}) << "\n"; return 0; } 
+7
c ++ initialization vector c ++ 11 initializer-list
source share
4 answers

The general use of std::initializer_list is an argument for container class designers (and the like), which makes it convenient to initialize these containers from several objects of the same type. Of course, you can use std::initializer_list otherwise, and then use the same syntax {} .

Since a std::initializer_list has a fixed size, it does not require dynamic allocation and, therefore, can be effectively implemented. A std::vector , on the other hand, requires dynamic memory allocation. Even in your simple example, it is unlikely that the compiler will optimize this overhead (avoid the intermediate std::vector and its dynamic memory allocation). Other than this, there is no difference in the results of your programs (although you should accept the const std::vector<int>& argument to avoid copying and the associated dynamic memory allocation).

+6
source share

The semantics of the two are completely different. initializer_list has pointer semantics, and vector value semantics.

In the first example, the compiler will generate code similar to the following:

 int const __temp_array[3] = {1, 2, 3}; cout << sumL(std::initializer_list<int>(__temp_array, __temp_array + 3)) << "\n"; 

This is explained in [dcl.init.list] / 5. As you can see, in sumL you have access to const pointers to the elements of the braced-init-list, this means that you have no other option but to copy the elements from the list.

In the case of sumV you could std::moved use elements from vector if necessary (provided that the parameter type is not const ).

Similarly, copying initializer_list makes small copies, i.e. only pointers will be copied, and copying vector , of course, means that the elements will be copied.

In your example, none of the above items matters, except for creating a vector dynamic memory allocation will be required, and there will be no initializer_list when building.

+3
source share

initializer_list uses an optimal storage location and prevents unnecessary calls, it is designed for light weight, and with vector - heap distribution, and there may be more copies / moves.

+3
source share

initalizer_list is not a generic container like std :: vector. The main goal is to initialize the object. If low eavesdropping and heap allocation are attractive to you, I would suggest looking at std :: array. This is an array with a fixed stack size, which has all the amenities of an STL container, which is essentially a thin shell on top of a c-array.

+1
source share

All Articles