使用迭代器删除对象类型的向量元素C++
我正在尝试编写一个函数,该函数从listAccounts中删除向量元素,具体取决于该向量元素的account_name。我写了这个:使用迭代器删除对象类型的向量元素C++
void Account::remove_account(string name) {
auto iter = listAccounts.begin();
for (; iter != listAccounts.end(); iter++) {
if ((*iter).account_name == name) {
listAccounts.erase(iter);
}
}
}
但我正在逐渐从载体去除分段故障,从我的理解它的意思,我试图访问我没有访问内存,但我不知道如何正确写这个。
一旦你擦除了迭代器所指向的元素,那个迭代器将变得无效。 (对于std::vector
,擦除元素之后的所有其他迭代器也会变得无效)。并且递增或解引用无效的迭代器具有未定义的行为。
你可以这样做(假设只有一个元素被删除):
void Account::remove_account(string name) {
auto iter = std::find_if(listAccounts.begin(), listAccounts.end(),
[&](const auto& s){ return s.account_name == name; });
if(iter != listAccounts.end())
listAccounts.erase(iter);
}
多个元素,那将是:
void Account::remove_account(string name) {
for(auto iter = listAccounts.begin(); iter != listAccounts.end();){
iter = std::find_if(iter, listAccounts.end(),
[&](const auto& s){ return s.account_name == name; });
if(iter != listAccounts.end())
iter = listAccounts.erase(iter);
}
}
如果你要只有一个元素去掉,然后你可以写
bool Account::remove_account(std::string &name)
{
auto it = std::find_if(listAccounts.begin(),
listAccounts.end(),
[&](const auto &item)
{
return item.account_name == name;
});
bool success = it != listAccounts.end();
if (success) listAccounts.erase(it);
return success;
}
至于你的代码然后在这个声明
listAccounts.erase(iter);
迭代器失效。所以你可能不会增加它。
如果容器被修改,迭代器将变为无效。 有两个很好的解决方案:
void Account::remove_account(const string& name) {
auto iter = listAccounts.begin();
while iter != listAccounts.end()) {
if (iter->account_name == name) {
iter = listAccounts.erase(iter);
} else {
++iter;
}
}
}
// or
void Account::remove_account(const string& name) {
listAccounts.erase(
std::remove_if(std::begin(listAccounts), std::end(listAccounts),
[&name](const auto& item) {
return item.account_name == name;
}),
std::end(listAccounts));
}
在第二种解决方案中,您可以在矢量上调用'remove'。我认为你的意思是“擦除”。 – navyblue
是的你是对的,修好了。 –
你想只删除一个元素或具有给定值的所有元素? –
副本说明您的for-loop在第一次擦除后变为无效。 if语句中需要'break'。 –
@Vlad来自莫斯科只有一个元素的矢量,其中account.name等于名称。 –