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);
我有一个 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);