Reputation: 4085
I have nested containers std::map<int, std::map<T, U> >
and want to populate them properly, either inserting a new sub map or appending to the sub map if the integer key exists. So I came up with something like the following example:
int n = ...;
int m = ...;
obj get_some_random_obj(int i, int j); // returns some object
std::map<int, std::map<int, obj> > container; // prepopulated container
// insert some new obj's. Create a new sub map if key i is not found in container,
// append to existing sub map otherwise
for(int i = 0; i < n; ++i) {
for(int j = 0; j < m; ++j) {
std::map<int, std::map<int, obj> >::iterator found = container.find(i);
obj newobj = get_some_random_obj(i,j);
std::pair<int, obj> newpair(j, newobj);
if(found != container.end()) {
found->second.insert(newpair);
} else {
std::map<int, obj> newmap;
newmap.insert(newpair);
container.insert(std::make_pair(i, newmap));
}
}
}
Two questions:
std::map<int, std::map<U,T>
with U
and T
arbitrary types? I have tried to come up with a template function, but couldn't get it to work at all.Thank you for your help!
Upvotes: 0
Views: 1027
Reputation: 76828
If you use operator[]
to access the elements, an empty one will be created if none exists yet (this works because std::map::value_type
has to be default-constructible):
std::map<int, std::map<int, obj> > foo;
foo[i][j] = some_object;
Note that, if foo[i][j]
already exists, it will be replaced by the new value.
Upvotes: 1
Reputation: 3266
std::map has an insert() function which returns a std::pair containing a boolean and an iterator.
If the boolean is true then the insert succeeded, and if the boolean is false then the key already exists and the iterator corresponds to the key so you can update the value.
Upvotes: 0
Reputation: 91270
container[i][j] = get_some_random_obj(i,j);
map's operator[]
inserts if the element isn't present.
Upvotes: 4
Reputation: 3598
I'm not sure here, but I think the std::multimap may be what you need. It will handle multiple objects per key.
Upvotes: 0