- Modern C++:Efficient and Scalable Application Development
- Richard Grimes Marius Bancila
- 438字
- 2021-06-10 18:28:05
Initializer lists
So far in this book, initializer lists have been treated as a kind of C++11 construct, a bit like built-in arrays. In fact, when you use the initializer list syntax using braces, the compiler actually creates an instance of the templated initialize_list class. If an initializer list is used to initialize another type (for example, to initialize a vector), the compiler creates an initialize_list object with the values given between the braces, and the container object is initialized using the initialize_list iterators. This ability to create an initialize_list object from a braced initializer list can be used by to give a function a variable number of parameters, albeit all of the parameters must be of the same type:
#include <initializer_list>
int sum(initializer_list<int> values)
{
int sum = 0;
for (int i : values) sum += i;
return sum;
}
int main()
{
cout << sum({}) << endl; // 0
cout << sum({-6, -5, -4, -3, -2, -1}) << endl; // -21
cout << sum({10, 20, 30}) << endl; // 60
return 0;
}
The sum function has a single parameter of initializer_list<int>, which can only be initialized with a list of integers. The initializer_list class has very few functions because it only exists to give access to the values in the braced list. Significantly, it implements a size function that returns the number of items in the list, and begin and end functions that return a pointer to the first item in the list, and to the position after the last item. These two functions are needed to give iterator access to the list, and it enables you to use the object with the ranged-for syntax.
In this example, the main function calls this function three times, each time with a braced initializer list, and the function will return a sum of the items in the list.
Clearly this technique means that each item in the variable parameter list has to be the same type (or a type that can be converted to the specified type). You would have the same result if the parameter had been a vector; the difference is that an initializer_list parameter requires less initialization.