如何从包含向量作为C ++中的值的地图中删除对象

时间:2017-07-28 07:31:44

标签: c++

我有一张地图,其中包含一个类型为Messages的矢量。

std::map<std::string, std::vector<Message>> storage;

class Message有3个成员变量。

class Message
{
private:
    std::string msg;
    std::string msg_type;
    int priority;
}

现在我正在尝试从地图中删除具有优先级(例如3)的对象。我正在使用以下功能。但它不起作用。

void deleteByMessagePriority(int priority)
{
    if (checkPriorityOfMessage(priority))
    {

        for (std::map<std::string, std::vector<Message>>::iterator it = storage.begin(); it != storage.end(); it++)
        {
            std::vector<Message> listOfMsgs = it->second;
            for (std::vector<Message>::iterator vec_it = listOfMsgs.begin(); vec_it != listOfMsgs.end(); vec_it++)

            //for(int index = 0;index < listOfMsgs.size();index++)
            {
                if (vec_it->getPriority() == priority)
                {
                    listOfMsgs.pop_back();
                }
            }


        }
    }
}

3 个答案:

答案 0 :(得分:2)

仔细看看:

            if (vec_it->getPriority() == priority)
            {
                listOfMsgs.pop_back();
            }

您正在查看一条消息(vec_it引用的消息)的优先级,但是如果匹配则删除了什么?

我不会自己编写循环,而是使用erasestd::remove_if一次性删除您在该向量中关注的所有项目。

for (auto & item : storage) {
    auto &vec = item.second;
    auto start_junk = std::remove_if(
        vec.begin(), vec.end(), 
        [=](Message const &m) { return m.priority == priority; });
    vec.erase(start_junk, vec.end());
}  

答案 1 :(得分:0)

if (vec_it->getPriority() == priority)
{
   listOfMsgs.pop_back();

pop_back()删除了您不想要的向量的最后一个元素。您要检查erase 还要记住erase()使迭代器无效,因此你需要在删除元素之后的下一个元素的迭代器,幸运的是我们可以使用返回值erase

if (vec_it->getPriority() == priority)
    {
       vec_it = listOfMsgs.erase(vec_it); //returns iterator to the element after vec_it which can also be `listOfMsgs.end()`

答案 2 :(得分:0)

std::vector<Message> listOfMsgs = it->second;
.
.
.
listOfMsgs.pop_back();

您正在复制列表,仅修改副本。你的意思是:

std::vector<Message>& listOfMsgs = it->second;

然后你可以继续删除元素。正如Gaurav Sehgal所说,使用erase的返回值:

std::vector<Message>::iterator vec_it = listOfMsgs.begin();
while (vec_it != listOfMsgs.end())
{
    if (vec_it->getPriority() == priority)
    {
        vec_it = listOfMsgs.erase(vec_it);
    }
    else
    {
        ++vec_it;
    }
}