簡體   English   中英

使用迭代器C ++刪除對象類型的向量元素

[英]Removing a vector element of object type using an iterator c++

我正在嘗試編寫一個函數,該函數根據該矢量元素的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);
        }
    }

}

但是從向量移除中我遇到了分段錯誤,據我了解,這意味着我試圖訪問我無權訪問的內存,但是我不確定如何正確地編寫它。

擦除迭代器指向的元素后,該迭代器將無效。 (對於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);  
    }
}

如果修改了容器,則迭代器無效。 有兩個好的解決方案:

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

如果您只刪除一個元素,則可以編寫

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

迭代器無效。 因此,您可能無法增加它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM