使用项目的指针从列表中删除该项目
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
的私有部分,所以您必须破解它——比如说,用不同的名称定义相同的结构模板。std::list<>::iterator
只是这个node
的包装。
无法完成。
我有一个类似的问题,那就是我使用epoll_wait并处理事件列表。事件结构只包含一个并集,其中最明显的类型是void*,用于指示找到的相关数据(包括文件描述符)。
std::list不允许通过指针删除元素,这似乎真的很愚蠢,因为显然有下一个和上一个指针。
我正在考虑重新使用Linux内核LIST宏来解决这个问题。过于抽象的问题是,您必须放弃与较低级别api的互操作性和通信。
- 从链接列表c++中删除一个项目
- 你能检查一下为什么在这个代码中从链接列表中删除项目不起作用吗
- 如何自动获取我的项目的路径并删除一些文件
- 如何从 CLion 的运行窗口中删除程序项目路径
- 类(可能是代理)的命名,允许在不修改基础容器的情况下对项目进行排序和删除
- C++ 从链表中删除项目时出现问题
- 仅从无序集合中删除一个项目
- Visual studio安装项目删除以前的版本
- 如何使用擦除和迭代器来删除二维向量中的项目
- 从 std::vector 中删除项目时"Iterator not incrementable"
- C++ priority_queue与自定义比较器并删除任何项目
- 从 QTreeView 中删除项目时取消选择所有行
- 如果为空,则从 QListWidget 中删除可编辑项目
- 从传递给新线程C++的矢量中删除项目
- C++ 链表删除了错误的项目
- 删除并清除组合框 Win32 API 中的所有项目
- 删除 iOS 项目中的 SDLKey 引用
- 如何将项目属性设置为删除警告MSB8004:中间目录不会以落后的斜线结束
- 如何创建一个函数,该函数可以从一个qtreewidget中删除项目并将其添加到另一个函数
- 在拖放 QML 列表中插入/删除项目使用 cpp 模型查看