如何在c ++ map中擦除键值对?

时间:2014-10-01 04:33:31

标签: c++ maps

我正在开发一个需要唯一键和值的项目,所以我决定使用地图。对于有人可能想要更改键值的情况,一切都有效。我不确定为什么,但它会导致碎片错误。我可以不这样做吗?

void Journal::set_id(int id){               // journal class
    if(join.count(id)){                     // join is: static map <int,string> join
        cout<<"Journal ID is already being used. Try again."<<endl;
    }
    else {
        join.erase (join.find(id));
        join.insert(pair<int,string>(id,name));
    }
}

3 个答案:

答案 0 :(得分:2)

你的逻辑是有缺陷的。

void Journal::set_id(int id){
    if(join.count(id)){
        cout<<"Journal ID is already being used. Try again."<<endl;
    }
    else {
        // When you hit this block of the code, there is nothing
        // in the map corresponding to 'id'.
        // join.find(id) returns the same iterator as join.end()
        // Calling erase() with that iterator is causing you the
        // problem.

        // Don't call erase. Just insert the new item.
        // join.erase (join.find(id));
        join.insert(pair<int,string>(id,name));
    }
}

答案 1 :(得分:1)

您刚检查过以确保id未被用作地图中的键。如果是,则发出错误。所以现在你知道 id不在地图中。如果地图中没有idjoin.find(id)将返回join.end(),因此您根本不需要致电find。但更重要的是,您再调用join.erase(join.end()),这是一个错误。

请参阅documention for std::map::erase() in cppreference

  

迭代器pos必须是有效且可解除引用的。因此,end()迭代器(有效但不可解除引用)不能用作pos的值。

答案 2 :(得分:0)

不是检查密钥是否存在,只有在找不到的情况下插入密钥,您可以通过插入项目来简化代码,然后检查返回值以查看插入是否成功(它赢得了&#39;如果那个钥匙已经存在了。)

void Journal::set_id(int id){
    if (!(join.insert(std::make_pair(id, name)).second))
        cout<<"Journal ID is already being used. Try again."<<endl;
}

这也应该提高速度,因为它只搜索树一次,而执行count然后insert的代码必须搜索两次。