Container changes in C++11
The recently approved C++11 standard brings a lot of welcome changes to C++ that modernize the language a little bit. Among the many changes, we find that containers have received some special love.
Initialization
C++ was long behind modern languages when it came to initializing containers. While you could do
[cpp]int a[] = {1, 2, 3};[/cpp]
for simple arrays, things tended to get more verbose for more complex containers:
[cpp]
vector
v.push_back(“One”);
v.push_back(“Two”);
v.push_back(“Three”);
[/cpp]
C++11 has introduced an easier, simpler way to initialize this:
[cpp]
vector
[/cpp]
The effects of the changes are even better for things like maps, which could get cumbersome quickly:
[cpp]
map<string, vector
vector
v1.push_back(“A”);
v1.push_back(“B”);
v1.push_back(“C”);
vector
v2.push_back(“A”);
v2.push_back(“B”);
v2.push_back(“C”);
m[“One”] = v1;
m[“Two”] = v2;
[/cpp]
This can now be expressed as:
[cpp]
map<string, vector
{"Two", {"Z", "Y", "X"}}};
[/cpp]
Much simpler and in line with most modern languages. As an aside, there’s another change in C++11 that would be easy to miss in the code above. The declaration
[cpp]map<string, vector
was illegal until now due to » always being evaluated to the right-shift operator; a space would always be required, like
[cpp]map<string, vector
No longer the case.
Iterating
Iterating through containers was also inconvenient. Iterating the simple vector v above:
[cpp]
for (vector
i != v.end(); i++)
cout << i << endl;[/cpp]
Modern languages have long had some foreach equivalent that allowed us easier ways to iterate through these structures without having to explicitly worry about iterators types. C++11 is finally catching up:
[cpp]
for (string s : v)
cout << s << endl;
[/cpp]
As well, C++11 brings in a new keyword, auto, that will evaluate to a type in compile-type. So instead of
[cpp]
for (map<string, vector
i != m.end(); i++) {
[/cpp]
we can now write
[cpp]
for (auto i = m.begin(); i != m.end(); i++) {
[/cpp]
and auto will evaluate to map<string, vector
Combining these changes, we move from the horrendous
[cpp]
for (map<string, vector
i != m.end(); i++)
for (vector<string>::iterator j = i->second.begin();
j != i->second.end(); j++)
cout << i->first << ': ' << *j << endl;
[/cpp]
to the much simpler
[cpp]
for (auto i : m)
for (auto j : i.second)
cout << i.first << ': ' << j << endl;
[/cpp]
Not bad.
C++11 support varies a lot from compiler to compiler, but all of the changes above are already supported in the latest versions of GCC, LLVM, and MSVC compilers.