[英]Remove item from a list using its pointer
我有一個指針p
(不是迭代器)到列表中的項目。 我可以使用p
從列表中刪除(擦除)項目嗎? 就像是:
mylist.erase(p);
到目前為止,我只能通過遍歷列表直到我到達位置p
處的項目,然后使用erase
方法來執行此操作,這看起來非常低效。
不,你必須使用迭代器。 我不明白為什么獲取指針比獲取迭代器更容易...
std::list
不是關聯的,所以你無法使用指針作為鍵直接刪除特定元素。
您發現自己處於這種情況的事實更多地指向可疑的設計,因為您是正確的,從集合中刪除項目的唯一方法是完全迭代它(即線性復雜性)
以下可能值得考慮:
如果可能,您可以將列表更改為std::multiset
(假設存在重復項),這將使直接訪問更有效。
如果設計允許,請更改您指向的項目以包含“已刪除”標記(或使用模板提供此標記),以允許您避免從集合中刪除對象,但快速將其標記為已刪除。 缺點是您的所有軟件都必須更改以適應此約定。
如果這是線性搜索的唯一一點,並且集合不大(<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.