std::vector 出现错误:"Cannot increment a vector past the end",同时想要擦除特定元素

std::vector Error shows up: "Cannot increment a vector past the end", while wanting to erase specific element

我有一个 classes 向量,class 有一个字符串名称,以及其他私有字段。

我想实现一个 void delete(string name) 函数,它根据字符串查找元素(向量中的每个 class 都有一个唯一的名称)。

然而经过简单的测试,它给了我一个错误“无法递增到最后”。

这是我的功能:

void delete_member(string member_name)
{
    int count = 0;

    for (auto it = member_list.begin(); it != member_list.end(); ++it, ++count)
        if (it->get_name() == member_name)
            member_list.erase(member_list.begin() + count);
}

就我搜索的答案而言,迭代器似乎不应该超过向量的 .end()。

这里的漏洞是什么?我正在使用相同的循环来迭代 add_member(Member m) 函数的向量,该函数完全可以正常工作

问题是您删除了元素但没有更新迭代器。为避免处理这些问题,最好使用 STL 算法。标准用法如下

C++20 前版本

member.erase(std::remove_if(member.begin(), member.end(), [&](const auto& val) 
{
  return val.get_name() == member_name;
}), member.end());

C++20

std::erase_if(member, [&](const auto& val) 
{
  return val.get_name() == member_name;
});

当您 erase 时,您正在使 it 无效,因此以后对它的使用是未定义的,包括在循环测试中递增和比较它。

可以

for (auto it = member_list.begin(); it != member_list.end(); )
    if (it->get_name() == member_name)
        it = member_list.erase(it);
    else
        it++

但是有一个标准<algorithm>

auto pred = [&](auto & member){ return member.get_name() == member_name; };
auto new_end = std::remove_if(member_list.begin(), member_list.end(), pred);
member_list.erase(new_end, member_list.end());

在C++20中,会更简单

auto pred = [&](auto & member){ return member.get_name() == member_name; };
std::erase_if(member_list, pred);