1

我正在尝试将一些值对插入到 std::map 中。在第一种情况下,我收到一个指向地图的指针,取消引用它并使用下标运算符分配一个值。IE

(*foo)[index] = bar;

后来,当我尝试遍历集合时,返回的键/值对在所有情况下都包含 null 的 value 属性,但第一个 (map.begin()) 项除外。奇怪的是,如果我通过地图的插入功能进行插入,一切都很好,即:

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++;
    }

}

我完全没主意了。请问有人有什么建议吗?

4

3 回答 3

12

在您的实际代码中,您有:

(*cycleNodes)[tmp->getId()] == tmp;

这不会将 tmp 分配到地图中,而是会引用地图创建一个空值(请参阅@Neil Butterworth) - 你有 == 而不是 =。你想要的是:

(*cycleNodes)[tmp->getId()] = tmp;
于 2009-04-27T13:21:50.763 回答
4

您应该知道 std::map 的 operator[] 将在映射中插入一个值,如果在这样的表达式中使用时不存在一个值:

if ( amap[x] == 42 ) {
   ...
}

如果值 x 不存在,则将创建一个并分配由值类型默认构造函数创建的值,或者为内置类型分配零。这几乎不是您想要的,您通常应该避免将 operator[] 与地图一起使用。

于 2009-04-27T13:00:59.503 回答
2

你的值类型有赋值运算符吗?

看看这个参考。[] 运算符返回对该值的非常量引用。如果您的分配错误或以某种意想不到的方式工作,这可能是原因。

另一方面,插入方法接受一个值并将其填充到地图中。[] 运算符使用默认构造函数构造一个对象,然后让我们使用它的赋值运算符为它赋值。

于 2009-04-27T12:57:59.013 回答