заполнить содержимое карт С ++ в области видимости - PullRequest
3 голосов
/ 19 октября 2010

Я пытаюсь заполнить содержимое карты с ++ внутри области видимости цикла.

#include <set>
#include <map>

map<int, set<int> > maps;

for (int i=0; i<10; i++) {
   set<int> seti;    // content: a set of integers
   seti.insert(i);
   seti.insert(...);
   maps.insert ( pair<int,set<int> >(i,seti) );
}

Вопрос в том, копирует ли maps.insert содержимое пары?Если экземпляр пары недопустим после каждой области видимости цикла, такой код должен завершиться ошибкой.

Как правильно генерировать содержимое карты (с указателем и новым экземпляром?) И как правильно очистить карту?

спасибо за любые предложения по передовому опыту.

--- UPDATE ---

map<int, set<int> >::iterator it;
int k      = (*it).first;     
set<int> v = (*it).second;       

теперь 'v' также является копией из реального экземпляра, хранящегося вкарта?
если да, то у меня нет возможности «напрямую» обновить содержимое карты.

Ответы [ 5 ]

6 голосов
/ 19 октября 2010

Вам не нужно явно создавать заданный объект, поскольку он будет создан на карте при доступе к нему с помощью оператора [].Следовательно, вы можете просто написать

#include <set>
#include <map>

map<int, set<int> > maps;

for (int i=0; i<10; i++) {
   maps[i].insert(i);
}
4 голосов
/ 19 октября 2010

Да, копирует содержимое.Таким образом, новая копия набора вставляется на каждой итерации цикла for.Если это то, что вы хотите, вы можете сделать это более кратко, используя функцию make_pair:

#include <set> 
#include <map> 

map<int, set<int> > maps; 

for (int i=0; i<10; i++) { 
   set<int> seti;    // content 
   seti.insert(i); 
   maps.insert ( std::make_pair(i,seti) ); 
} 

Мне не понятно, почему вы хотите набор только с одним элементом, если вы не планируете добавлять элементык нему в будущем.

ОБНОВЛЕНО: В ответ на ваше обновление.Пока значение на вашей карте является контейнером базового типа значения, любые изменения, которые вы вносите в него, не будут влиять на исходное значение, вставленное в карту.

1 голос
/ 19 октября 2010

Я должен признать, что имя переменной maps в следующей строке смутило меня

map<int, set<int> > maps;

Оно дало представление о том, что существует много карт, тогда как в действительности существует только одна.

Требуются две петли:

  • один для построения set из int и
  • второй, чтобы вставить эти set s в map.

Вот пример кода

typedef std::set< int > IntSet;
typedef std::map< int, IntSet > MapOfIntSet;

MapOfIntSet myMap;     // container

for( int i = 0; i < N; ++i ) {
    IntSet intSet;
    for( int j = i + 1; j < N; ++j ) {
        intSet.insert( j );
    }

    // Both the following line does the same, any one can be used
    // myMap.insert( make_pair( i, intSet ) );
    myMap[ i ] = intSet;
}

A полная программа с выходом загружена на кодовую панель.

1 голос
/ 19 октября 2010

Код, который вы разместили, должен работать просто отлично.Из-за семантики обычной типа значения будут скопированы туда, где они принадлежат.Карта (и все экземпляры обычных типов, содержащихся в карте) будут разрушаться должным образом, когда они выпадают из области видимости.

0 голосов
/ 19 октября 2010

Да, весь набор копируется внутрь, что является узким местом для производительности.Мне не нравятся предлагаемые решения из-за этого.А также, как вы просите, используя указатели, вы можете сделать это безопасно, используя boost::shared_ptr.Код может выглядеть следующим образом:

#include <set>
#include <map>
#include <boost/shared_ptr.hpp>

// I add typedefs for clarity
typedef boost::shared_ptr< set<int> > set_ptr;

using namespace std;

map<int, set_ptr > maps;

for (int i=0; i<10; i++) {
   set_ptr seti( new set<int>());    // content
   seti->insert(i);
   maps.insert ( std::make_pair(i,seti) );
}

Обратите внимание, что теперь вы копируете только безопасные указатели, которые удаляются при удалении maps.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...