簡體   English   中英

使用指針從列表中刪除項目

[英]Remove item from a list using its pointer

我有一個指針p (不是迭代器)到列表中的項目。 我可以使用p從列表中刪除(擦除)項目嗎? 就像是:

mylist.erase(p);

到目前為止,我只能通過遍歷列表直到我到達位置p處的項目,然后使用erase方法來執行此操作,這看起來非常低效。

不,你必須使用迭代器。 我不明白為什么獲取指針比獲取迭代器更容易...

std::list不是關聯的,所以你無法使用指針作為鍵直接刪除特定元素。

您發現自己處於這種情況的事實更多地指向可疑的設計,因為您是正確的,從集合中刪除項目的唯一方法是完全迭代它(即線性復雜性)

以下可能值得考慮:

  1. 如果可能,您可以將列表更改為std::multiset (假設存在重復項),這將使直接訪問更有效。

  2. 如果設計允許,請更改您指向的項目以包含“已刪除”標記(或使用模板提供此標記),以允許您避免從集合中刪除對象,但快速將其標記為已刪除。 缺點是您的所有軟件都必須更改以適應此約定。

  3. 如果這是線性搜索的唯一一點,並且集合不大(<20項說。)為了方便起見,只需按照你的建議進行線性搜索,但在代碼中留下一個大的注釋,表明你是如何“ 完全得到 “這是多么低效。 你可能會發現,如果有的話,這在任何情況下都不會成為一個有形的問題。

我猜這3可能是你最好的選擇。 :)

這不是我的建議,而是回答這個問題:

只有在您准備進入未定義行為和不可移植性的禁止世界時才能讀取:

有一種不可移植的方法可以從T*指針到list<T>的元素創建一個迭代器。 您需要查看您的std庫list頭文件。 對於Gnu g++它包含stl_list.h ,其中std::list定義是。 最典型的std::list<T>由類似於此的節點組成:

template <class T>
struct Node {
   T item;
   Node* prev;
   Node* next;
};

有了指向Node<T>::item指針,你可以使用offsetof計算這個節點指針。 請注意,此Node模板可能是std::list的私有部分,因此您必須破解它 - 假設通過定義具有不同名稱的相同struct模板。 std::list<>::iterator只是這個node包裝器。

它無法完成。

我有類似的問題,因為我正在使用epoll_wait並處理事件列表。 事件結構只包含一個聯合,其中最明顯的類型是void *,用於指示找到的哪些數據(包括文件描述符)。

std :: list不允許你通過指針刪除元素似乎真的很愚蠢,因為顯然有一個下一個和前一個指針。

我正在考慮重新使用Linux內核LIST宏來解決這個問題。 抽象過多的問題是你必須放棄與低級api的互操作性和通信。

暫無
暫無

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

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