bug estranho ao inserir em C ++ std :: map
-
16-09-2019 - |
Pergunta
Eu estou tentando inserir alguns pares de valores em um std :: map. No primeiro caso, recebo um ponteiro para o mapa, desreferenciava-lo e usar o operador subscrito para atribuir um valor. ou seja
(*foo)[index] = bar;
pares chave Mais tarde, quando eu tento iteração sobre a coleção, eu estou retornou / valor que contêm nulo para o atributo de valor em todos os casos, exceto para o primeiro (map.begin) () item. O estranho é, se eu fizer a inserção através da função de inserção do mapa, tudo está bem, ou seja:
foo->insert(std::pair<KeyType,ValueType>(myKey, myValue));
Por que isso seria? não são os dois métodos funcionalmente equivalentes? Eu colei alguns trechos de código real abaixo de contexto
...
typedef std::map<int, SCNode*> SCNodeMap;
...
void StemAndCycle::getCycleNodes(SCNodeMap* cycleNodes)
{
(*cycleNodes)[root->getId()] = root;
SCNode* tmp = root->getSucc();
while(tmp->getId() != root->getId())
{
// (*cycleNodes)[tmp->getId()] == tmp; // crashes (in loop below)
cycleNodes->insert(std::pair<int, SCNode*>(tmp->getId(), tmp));//OK
std::pair<int, SCNode*> it = *(cycleNodes->find(tmp->getId()));
tmp = tmp->getSucc();
}
// debugging; print ids of all the SCNode objects in the collection
std::map<int, SCNode*>::iterator it = cycleNodes->begin();
while(it != cycleNodes->end())
{
std::pair<int, SCNode*> p = (*it);
SCNode* tmp = (*it).second; // null except for it = cycleNodes->begin()
std::cout << "tmp node id: "<<tmp->getId()<<std::endl;
it++;
}
}
Eu estou fora de ideias. Alguém tem alguma sugestão, por favor?
Solução
Em seu código real que você tem:
(*cycleNodes)[tmp->getId()] == tmp;
Isto não vai tmp atribuir no mapa, mas em vez disso, referência para o mapa criando um valor vazio (veja @Neil Butterworth) - você tem == em vez de =. O que você quer é:
(*cycleNodes)[tmp->getId()] = tmp;
Outras dicas
Você deve estar ciente de que operador [] para std :: mapa irá inserir um valor para o mapa se não existir quando usado em expressões como esta:
if ( amap[x] == 42 ) {
...
}
Se o valor x não existe, será criado e atribuído o valor criado pelo construtor padrão tipos de valor, ou zero para o built-in tipos. Isso quase nunca é o que você quer, e você geralmente deve evitar o uso de operador [] com mapas.
Será que o seu tipo de valor tem um operador de atribuição?
Dê uma olhada este referência. Os [] operador retorna uma referência não-const para o valor. Se a sua atribuição está errado ou alguma forma funciona de uma forma inesperada esta pode ser a causa.
O método de inserção, por outro lado tem um valor e enfia-a no mapa. O operador [] constrói um objeto com o construtor padrão, então vamos lhe coisas atribuir-lhe a usá-lo de operador de atribuição.