使用迭代器c ++

时间:2017-10-15 19:54:13

标签: c++ algorithm object vector erase

我正在尝试编写一个函数,该函数根据该向量元素的account_name从listAccounts中删除向量元素。我写了这个:

void Account::remove_account(string name) {

    auto iter = listAccounts.begin();

    for ( ; iter !=  listAccounts.end(); iter++) {
        if ((*iter).account_name == name) {
            listAccounts.erase(iter);
        }
    }

}

但是我从矢量删除中得到了分段错误,据我所知,这意味着我试图访问我无法访问的内存,但我不确定如何正确地写这个。 / p>

3 个答案:

答案 0 :(得分:2)

删除迭代器指向的元素后,该迭代器将变为无效。 (对于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);  
    }
}

答案 1 :(得分:2)

如果容器被修改,迭代器将变为无效。 有两个很好的解决方案:

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));
}

答案 2 :(得分:0)

如果您要删除一个元素,则可以编写

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

迭代器变得无效。所以你可能不会增加它。