【问题标题】:std::vector Error shows up: "Cannot increment a vector past the end", while wanting to erase specific element出现 std::vector 错误:“无法将向量递增到末尾”,同时想要擦除特定元素
【发布时间】:2020-12-07 09:19:31
【问题描述】:

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

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

但是经过简单的测试,它给了我一个错误“不能增加超过末尾”。

这是我的功能:

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) 函数的向量,该函数完全正常

【问题讨论】:

  • it 在调用擦除后失效,因此您无法继续迭代。找到元素时添加break; 或将it 重新分配给erase 的结果

标签: c++ c++11 vector stdvector


【解决方案1】:

问题是您删除了元素但没有更新迭代器。为了避免处理这些,最好使用 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;
});

【讨论】:

    【解决方案2】:

    当你 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);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-03-30
      • 1970-01-01
      • 1970-01-01
      • 2016-03-31
      • 1970-01-01
      • 2011-10-23
      • 2021-08-06
      相关资源
      最近更新 更多