Roberto Selbach

About |  Blog |  Archive

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.


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:

vector v;

C++11 has introduced an easier, simpler way to initialize this:

vector v = {“One”, “Two”, “Three”};

The effects of the changes are even better for things like maps, which could get cumbersome quickly:

map<string, vector > m;
vector v1;

vector v2;

m[“One”] = v1;
m[“Two”] = v2;

This can now be expressed as:

map<string, vector> m = One,

                             {"Two", {"Z", "Y", "X"}}};


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> m;[/cpp]

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 > m[/cpp]

No longer the case.


Iterating through containers was also inconvenient. Iterating the simple vector v above:

for (vector::iterator i = v.begin();

 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:

for (string s : v)

cout << s << endl;


As well, C++11 brings in a new keyword, auto, that will evaluate to a type in compile-type. So instead of

for (map<string, vector >::iterator i = m.begin();

 i != m.end(); i++) {


we can now write

for (auto i = m.begin(); i != m.end(); i++) {

and auto will evaluate to map<string, vector>::iterator.

Combining these changes, we move from the horrendous

for (map<string, vector >::iterator i = m.begin();

 i != m.end(); i++)
for (vector<string>::iterator j = i->second.begin();
     j != i->second.end(); j++)
    cout << i->first << ': ' << *j << endl;


to the much simpler

for (auto i : m)

for (auto j : i.second)
    cout << i.first << ': ' << j << endl;


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.