2012-03-05 14 views
0

最初C++マップの反復処理の相違点

私は描画関数を含む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); 
} 

私の質問は、1つの機能と他の機能ではないのですか?

2番目の質問は、名前を付けずにNodeManagerクラスにすべてのノードを格納する別の方法です。ほんの単純なリスト?

+3

最初の 'while'ループでは' draw'を呼びません。それはタイプミスか実際のエラーですか? – Naveen

+2

アンダースコアの大文字は予約されているので使用しないでください。使用すると、未定義の動作になります。 –

答えて

5

最初のループで++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

- >しかし、それは動作しません。

第1バージョン(whileループ)と第2バージョン(forループ)には大きな違いがあるためです。

  1. while()あなたが呼び出すwhile()でイテレータ
  2. を増大させるための任意のit++を持っていないだけでsetX()

- >内のすべてのノードを格納するための別の方法であるもの NodeManagerクラスに名前を付ける必要はありませんか?

あなたは、単に配列

  • std::setをしたい場合は、Node*
  • に基づいて、ノードを見つけることができるようにしたい場合は、あなたが

    1. std::vector(または同等)、探しているかもしれませ
    +0

    99%の確率で 'vector' /' set'を望みますが、 'deque'を忘れないでください! ( 'list'を忘れてください...) –