问题描述
我试图保留一个特定(基)类实例的全局列表,以便我可以随时通过遍历该全局列表来跟踪它们.
I'm trying to keep a global list of a particular (base) class's instances so that I can track them down by iterating through this global list at any time.
我认为解决这个问题的最合适方法是使用侵入式列表.我听说有人可以通过例如研究Linux内核来遇到这些生物.
I believe the most proper way to address this is with an intrusive list. I have heard that one can encounter these creatures by digging into the Linux kernel, for example.
在我所处的情况下,我实际上并不需要这种性能保证,而使用侵入式列表会使我的事情变得有些复杂.
In the situation where I'm in, I don't really need such guarantees of performance, and using intrusive lists will complicate matters somewhat for me.
到目前为止,这是我实现一个了解所有实例的类的概念的内容.
Here's what I've got so far to implement this concept of a class that knows about all of its instances.
class A {
static std::forward_list<A*> globallist;
std::forward_list<A*>::iterator listhandle;
public:
A() {
globallist.push_front(this);
listhandle = globallist.begin();
}
virtual ~A() {
globallist.erase_after(...); // problem
}
};
问题是没有forward_list::erase()
,而且确实不像将globallist.before_begin()
保存在ctor中对我有很大帮助.我绝不应该取消引用before_begin()
的迭代器.它实际上会保持住该位置吗?如果我保存before_begin
的迭代器,然后保存push_front()
一个新项,则该迭代器可能仍然无法取消引用,但是可以发送给erase_after()
使用吗?
The problem is that there is no forward_list::erase()
, and it really does not appear like saving globallist.before_begin()
in the ctor would do me much good. I'm never supposed to dereference before_begin()
's iterator. Will it actually hold on to the position? If I save out before_begin
's iterator, and then push_front()
a new item, that iterator is probably still not capable of being dereferenced, but will it be serviceable for sending to erase_after()
?
推荐答案
forward_list
是一个单链表.要在其中删除一个节点,您必须以某种方式拥有一个指向上一个节点的指针.例如,您可以执行以下操作:
forward_list
is a singly linked list. To remove a node in the middle of that, you must have a pointer to previous node, somehow. For example, you could do something like this:
class A {
static std::forward_list<A*> globallist;
std::forward_list<A*>::iterator prev_node;
public:
A() {
A* old_head = globallist.front();
globallist.push_front(this);
prev_node = globallist.before_begin();
old_head->prev_node = globallist.begin();
}
};
将第一个元素放入一个空列表的情况以及删除逻辑留给读者练习(删除时,将prev_node
复制到下一个节点的prev_node
).
The case of pushing the first element into an empty list, as well as the removal logic, are left as an exercise for the reader (when removing, copy your prev_node
to the next node's prev_node
).
或者,只需使用std::list
并避免所有此类麻烦.
Or, just use std::list
and avoid all this trouble.
这篇关于std :: forward_list-用存储的迭代器擦除的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!