开发者

Is there a more elegant way to conditionally insert into a std::map of std::maps?

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:

  • Is there a more elegant (more efficient?) way to write this?
  • How can one make the above code more abstract, so that it becomes possible to populate containers with type std::map<int, std::map<U,T> with U and T arbitrary types? I ha开发者_开发百科ve tried to come up with a template function, but couldn't get it to work at all.

Thank you for your help!


container[i][j] = get_some_random_obj(i,j);

map's operator[] inserts if the element isn't present.


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.


I'm not sure here, but I think the std::multimap may be what you need. It will handle multiple objects per key.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜