簡體   English   中英

通過引用從std :: list中刪除元素

[英]remove element from std::list by reference

std::list<Reader> readers;

readers.push_back(Reader());

Reader& r = *(readers.begin());

/* at this point, the exact place in list, where the reader was picked out, is forgotten. 
   Only 'r' shows which element of the list it is. */

readers.erase(r); //<---how to do this?

客戶端從經理/調度程序獲取新實例的“讀者”對象。 管理器維護一個內部列表,其中包含已發送的任何內容,如果“感興趣的每個人”通過觀察調度的讀者池來獲取緩存的數據,則會使緩存的數據無效/釋放。

當客戶端不再對數據感興趣時,它應該將讀取器返回給管理器以從池中刪除。 但我不希望客戶端保留一個迭代器 - 它對管理者和讀者池的膽量絕對不感興趣; 它只需要這個自己的讀者,而不是指向它的迭代器。 因此,對於刪除,它會調用管理器的清理函數,並引用該單個讀取器。

是否有更好的方法從列表中刪除該閱讀器,而不是遍歷整個列表以搜索引用所引導的那個閱讀器?

std::removeerase結合使用

readers.erase(std::remove(readers.begin(), readers.end(), r), readers.end());

此外,您不能通過值從列表中刪除元素,而無需迭代它。 如果你仔細想想,它甚至沒有任何意義,因為列表中的指針必須進行更新。

如果您只引用該對象,則您的選項是使用std::list::remove

readers.remove(r);

std::findstd::list::erase結合使用

readers.erase(std::find(readers.begin(), readers.end(), r));

前者必須遍歷整個列表,而后者在找到第一個元素時將停止,然后將其刪除。 對於大型列表,這可以產生很大的不同。

這兩個選項僅在項目唯一時才有效。 如果你有非唯一元素,那么你可以使用std::find_if並提供一個比較項目地址的函子。 這樣你就可以保證你只刪除引用實際引用的對象而不是比較等於。

readers.erase(std::find_if(readers.begin(), readers.end(), [&](const auto& e) {return &r == &e;}));

您可以比較指針以檢查它們是否是同一個對象

readers.remove_if([r=&r](auto& x){return &x==r;});

如果列表可以包含相等的值,那么您可以執行以下操作

#include <iostream>
#include <list>

int main()
{
    struct Reader { std::pair<char, int> p; };
    std::list<Reader> readers;

    readers.push_back({{ 'A', 1 } });
    readers.push_back({ { 'A', 2 } });
    Reader &rr = readers.back();
    readers.push_back({ { 'A', 3 } });

    readers.remove_if([&rr](const Reader &r) { return &r == &rr; });

    for (const auto &r : readers)
    {
        std::cout << r.p.first << ' ' << r.p.second << std::endl;
    }

    return 0;
}

程序輸出是

A 1
A 3

暫無
暫無

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

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