Есть ли более элегантный способ условно вставить в std :: map из std :: maps? - PullRequest
0 голосов
/ 07 апреля 2011

У меня есть вложенные контейнеры std::map<int, std::map<T, U> >, и я хочу их правильно заполнить, либо вставив новую субкарту, либо добавив ее к субкарте, если существует целочисленный ключ. Итак, я придумал что-то вроде следующего примера:

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));
        }
    }
}

Два вопроса:

  • Есть ли более элегантный (более эффективный?) Способ написать это?
  • Как сделать приведенный выше код более абстрактным, чтобы можно было заполнять контейнеры с типами std::map<int, std::map<U,T> произвольными типами U и T? Я пытался придумать функцию шаблона, но не смог заставить ее работать вообще.

Спасибо за помощь!

Ответы [ 4 ]

4 голосов
/ 07 апреля 2011
container[i][j] = get_some_random_obj(i,j);

карта operator[] вставляется, если элемент отсутствует.

1 голос
/ 07 апреля 2011

Если вы используете operator[] для доступа к элементам, будет создан пустой, если его еще нет (это работает, потому что std::map::value_type должен быть конструируемым по умолчанию):

std::map<int, std::map<int, obj> > foo;
foo[i][j] = some_object;

Обратите внимание, что, если foo[i][j] уже существует, он будет заменен новым значением.

0 голосов
/ 07 апреля 2011

std :: map имеет функцию insert (), которая возвращает std :: pair, содержащую логическое значение и итератор.

Если логическое значение истинно, то вставка прошла успешно, а если логическое значение ложно, тоключ уже существует, и итератор соответствует ключу, поэтому вы можете обновить значение.

0 голосов
/ 07 апреля 2011

Я не уверен здесь, но я думаю, что std :: multimap может быть тем, что вам нужно. Он будет обрабатывать несколько объектов на ключ.

...