If developers want to declare and initialize an array of five integers, they can do something like:
int a[] = { 10, 20, 5, 45, 22 };
But before C++11, what used to happen when developers wanted to do the same thing using a container available in the standard library, like std::vector<T>? Something like:
std::vector<int> a = { 10, 20, 5, 45, 22 };
Exactly!!! The code would not compile. Initializer lists were only available for (as Marcin Łoś mentions in the comments section below) aggregate types… And then C++11 was published! :)
As mentioned, starting in C++11, the code shown above is perfectly valid and works as expected; that’s because C++11 introduced support for initializer lists for any data type.
So, the next question would be… How can a developer create their own classes that support these initializer lists?
The answer: The standard library includes a new template class called std::initializer_list<T>. When the compiler finds a declaration with an initialization similar to the one shown above { 1, 2, 3, 4, 5 };, it looks for a constructor that accepts an std::initializer_list<T> as an argument. If found, the compiler creates an instance of the that class, passing the values inside the curly brackets, and invokes the constructor.
The std::initializer_list<T> object can be iterated using a standard iterator.
The example shown below is a wrapper around a vector that implements support for std::initializer_list<T>:
#include <vector>
#include <initializer_list>
template <typename T>
class MyList
{
private:
std::vector<T> _items;
public:
MyList() { }
MyList(const std::initializer_list<T>& x)
{
for (auto i = x.cbegin(); i != x.cend(); ++i)
_items.push_back(*i);
}
};
With this implementation, an instance of MyList can be created in this way:
MyList<int> x = { 10, 20, 1, 4, 8, 16, 9 };
MyList<std::string> y = { "hello", "world", "of", "c++", "programmers"};
I really enjoy your C++11 articles :)
This one contains, however, a minor mistake. In C++03, initializer lists were available for ‘aggregate’ types, not only built-ones. ‘Aggregate type’ is an array, or a class satysfying certain restrictions (has no user-declared ctor, no non-public non-static data, no base classes and no virtual functions).
Is “Aggregate type” the same as “POC” as described in:
http://en.wikipedia.org/wiki/Plain_old_data_structure
?
Thanks for reading me and clarifying a lot of stuff right here :)
The most significant difference between these two is that POD’s member types are severely restricted, while aggregate can contain pretty much anything.
Precisely, POD struct/union is an aggregate satisfying following conditions:
– has no user-defined copy-assigmnent operator
– has no user-defined destructor
– has no non-static member being non-POD, array-of-non-POD or reference
For longer description of these concepts (aggregate, POD) see: http://stackoverflow.com/questions/4178175/what-are-aggregates-and-pods-and-how-why-are-they-special/4178176#4178176
(this post is not mine)
Note: these are C++03 definitions, current (C++11) definitions are slightly altered to accomodate new concepts.