C ++のstdに挿入しながら奇妙なバグ::マップ
-
16-09-2019 - |
質問
私はのstd ::マップにいくつかの値のペアを挿入しようとしています。 最初のケースでは、私はそれを間接参照、マップへのポインタを受け取り、値を割り当てること添字演算子を使用します。即ち
(*foo)[index] = bar;
私はコレクションを反復処理しようとすると、その後、私が最初に(map.begin())の項目を除くすべてのケースでvalue属性にnullを含んでキー/値のペアを返されています。奇妙なことは、私はマップの挿入機能を経由して挿入を行う場合は、すべてのものは、よくある、あるすなわちます:
foo->insert(std::pair<KeyType,ValueType>(myKey, myValue));
これはなぜでしょうか?機能的に同等の二つの方法がありませんか?私は、コンテキストについては、以下の実際のコードのいくつかのスニペットを貼り付けました。
...
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++;
}
}
私はすべてのアイデアをよ。誰もが提案をしてください持っていますか?
解決
あなたの実際のコードで、あなたは持っています:
(*cycleNodes)[tmp->getId()] == tmp;
このマップにTMPを割り当てませんが、代わりに空の値を作成するマップに参照します(@Neilバターワースを参照してください) - あなたの代わりに=の==ています。何がしたいことはあります:
(*cycleNodes)[tmp->getId()] = tmp;
他のヒント
次のような式で使用する場合が存在しない場合、オペレータは[]のstd ::マップがマップに値を挿入することを認識する必要があります
if ( amap[x] == 42 ) {
...
}
値xが存在しない場合は、、一方が作成され、ビルトインタイプの値タイプデフォルトコンストラクタ、またはゼロで作成された値が割り当てられます。これは、あなたが望むものはほとんどことはありません、あなたは一般的にマップして、[]演算子の使用を避ける必要があります。
あなたの値の型が代入演算子を持っていますか?
この参照のを見てみましょう。 []演算子は、値の非const参照を返します。あなたの割り当てが間違っているか、何らかの形で予期しない方法で動作する場合は、これが原因である可能性があります。
一方の挿入方法は、値を取得し、マップにそれを詰め込みます。 []演算子は、デフォルトコンストラクタを持つオブジェクトを作成し、その後のあなたはそれが代入演算子のです使用して、それにものを割り当てることができます。