As Steve Townsend noted, std::map
is similar in concept but has a different implementation.
Creating your nested container in C++ is a little more verbose:
#include <tr1/unordered_map>
#include <iostream>
typedef std::tr1::unordered_map< std::string, int > Inner;
typedef std::tr1::unordered_map< std::string, Inner > Outer;
int main()
{
Outer foo;
Inner::value_type bar1_data[] = {
Inner::value_type("Default", 0),
Inner::value_type("Value", 0),
};
const size_t n_bar1_data = sizeof(bar1_data) / sizeof(*bar1_data);
foo["bar1"] = Inner(bar1_data, bar1_data + n_bar1_data);
Inner::value_type bar2_data[] = {
Inner::value_type("Default", 2),
Inner::value_type("value", 5),
Inner::value_type("other", 4),
};
const size_t n_bar2_data = sizeof(bar2_data) / sizeof(*bar2_data);
foo["bar2"] = Inner(bar2_data, bar2_data + n_bar2_data);
As documented in perlref, arrows between subscripting brackets are optional, so you could have written (commented to maintain the flow of the C++ program)
// $foo{"bar1"}{"Default"} = 15;
which is pretty close to C++:
foo["bar1"]["Default"] = 15;
For good measure, we print the resulting structure and return 0 from main
:
for (Outer::const_iterator o = foo.begin(); o != foo.end(); ++o) {
std::cout << o->first << ":\n";
for (Inner::const_iterator i = o->second.begin(); i != o->second.end(); ++i)
std::cout << " - " << i->first << " => " << i->second << '\n';
}
return 0;
}
Output:
bar1:
- Value => 0
- Default => 15
bar2:
- Default => 2
- value => 5
- other => 4
NOTE: Input and output have the same order in this toy program, but don't depend on this behavior!
If instead you prefer to use boost::unordered_map
, change a few lines at the top of your program:
#include <boost/unordered_map.hpp>
typedef boost::unordered_map< std::string, int > Inner;
typedef boost::unordered_map< std::string, Inner > Outer;