Различия в итерации карты C ++ - PullRequest
0 голосов
/ 05 марта 2012

Первый

У меня есть класс Node, который содержит функцию рисования.Узлы содержатся на карте, например:

map<std::string, Node*>

Когда я использую итератор для рисования всех узлов на карте, ничего не происходит.(gc - это графический контекст, который я передаю функции рисования)

std::map<std::string, Node*>::const_iterator itr = _Nodes.begin();
while(itr != _Nodes.end())
{
    itr->second->setX(100);
}

Но это не работает.Однако, если я построю свой итератор по-другому, он будет работать.

std::map<std::string, Node*>::const_iterator end = _Nodes.end();
for(std::map<std::string, Node*>::const_iterator it = _Nodes.begin(); it != end; ++it){
    it->second->draw(gc);
    it->second->setSize(100);
}

Мой вопрос: почему работает один, а не другой?

Второй вопрос: какой альтернативный способ хранить всеузлы в классе NodeManager, не называя их?Простой список?

Ответы [ 2 ]

5 голосов
/ 05 марта 2012

Вы не звоните ++itr в первом цикле.Ваш итератор никогда не изменится.

Должно быть:

std::map<std::string, Node*>::const_iterator itr = _Nodes.begin(); 
while(itr != _Nodes.end()) 
{ 
    itr->second->setX(100); 
    ++itr;
} 

PS: если вы можете использовать C ++ 11, это гораздо удобнее:

auto itr = _Nodes.begin();

PPS: _Node это запрещенное имя.Имена, начинающиеся с подчеркивания + заглавные, зарезервированы стандартом.

PPPS: В первом примере вы, вероятно, хотите сохранить end() в переменной, чтобы сохранить немного производительности (но очень мало).

4 голосов
/ 05 марта 2012

-> Но это не работает.

Поскольку между 1-й версией (цикл while) и второй версией (цикл for) есть существенное различие.

  1. while() не имеет it++ для увеличения итератора
  2. В while() вы звоните только setX()

-> какой альтернативный способ хранить все узлы в классе NodeManager без необходимости их именования?

Может быть, вы ищете,

  1. std::vector (или эквиваленты), если вам нужен просто массив
  2. std::set, если вы хотите найти узел, основанный на Node*
...