繁体   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