将迭代器存储在容器内

发布于 2024-07-28 01:27:30 字数 303 浏览 2 评论 0原文

我正在构建另一个应用程序将使用的 DLL。 我想在从函数调用返回之前将某些数据的当前状态全局存储在 DLL 的内存中,以便我可以在下次调用该函数时重用状态。

为此,我必须保存一些迭代器。 我使用 std::stack 来存储所有其他数据,但我不确定是否也可以使用迭代器来做到这一点。

将列表迭代器放入容器类中是否安全? 如果没有,您能否建议一种方法来存储指向列表中元素的指针,以便我以后可以使用它?

我知道使用向量来存储我的数据而不是列表可以让我存储下标并非常轻松地重用它,但不幸的是我不得不仅使用 std::list。

I am building a DLL that another application would use. I want to store the current state of some data globally in the DLL's memory before returning from the function call so that I could reuse state on the next call to the function.

For doing this, I'm having to save some iterators. I'm using a std::stack to store all other data, but I wasn't sure if I could do that with the iterators also.

Is it safe to put list iterators inside container classes? If not, could you suggest a way to store a pointer to an element in a list so that I can use it later?

I know using a vector to store my data instead of a list would have allowed me to store the subscript and reuse it very easily, but unfortunately I'm having to use only an std::list.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

奈何桥上唱咆哮 2024-08-04 01:32:06

相同的规则适用于存储在局部变量中的迭代器,就像在寿命较长的数据结构中一样:只要容器允许,它就会保持有效。

对于列表来说,这意味着:只要它指向的节点没有被删除,迭代器就保持有效。 显然,当列表被破坏时,节点会被删除......

The same rule applies to an iterator stored in a local variable as in a longer lived data structure: it will stay valid as long as the container allows.

For a list, this means: as long as the node it points to is not deleted, the iterator stays valid. Obviously the node gets deleted when the list is destructed...

池予 2024-08-04 01:31:28

存储列表的迭代器应该没问题。 除非您从存储迭代器的列表中删除相同的元素,否则它不会失效。 以下引用自 SGI 网站:

列表有一个重要的属性:
插入和拼接不
使列表元素的迭代器无效,
即使删除也只会无效
指向的迭代器
被删除的元素

注意,存储的迭代器的前一个和下一个元素可能会更改。 但迭代器本身仍然有效。

Storing the iterator for the list should be fine. It will not get invalidated unless you remove the same element from the list for which you have stored the iterator. Following quote from SGI site:

Lists have the important property that
insertion and splicing do not
invalidate iterators to list elements,
and that even removal invalidates only
the iterators that point to the
elements that are removed

However, note that the previous and next element of the stored iterator may change. But the iterator itself will remain valid.

掩于岁月 2024-08-04 01:30:49

这可能是题外话,但只是一个提示...

请注意,您的函数/数据结构对于读取操作可能是线程不安全的。 有一种基本的线程安全性,其中读取操作不需要同步。 如果您要存储调用者从您的结构中读取了多少数据,则将使整个概念线程不安全并且使用起来有点不自然。 因为没有人认为读取是全状态操作。

如果两个线程要调用它,它们要么需要同步调用,要么您的数据结构可能最终陷入竞争状态。 这种设计的问题是两个线程必须能够访问公共同步变量。

我建议创建两个重载函数。 两者都是无状态的,但其中之一应该接受提示迭代器,从哪里开始下一次读取/搜索/检索等。这就是 STL 中分配器的实现方式。 您可以向分配器传递一个提示指针(默认为 0),以便它更快地找到新的内存块。

问候,
奥瓦内斯

This might be offtopic, but just a hint...

Be aware, that your function(s)/data structure would probably be thread unsafe for read operations. There is a kind of basic thread safety where read operations do not require synchronization. If you are going to store the sate how much the caller read from your structure it will make the whole concept thread unsafe and a bit unnatural to use. Because nobody assumes a read to be state-full operation.

If two threads are going to call it they will either need to synchronize the calls or your data structure might end-up in a race condition. The problem in such a design is that both threads must have access to a common synchronization variable.

I would suggest making two overloaded functions. Both are stateless, but one of them should accept a hint iterator, where to start next read/search/retrieval etc. This is e.g. how Allocator in STL is implemented. You can pass to allocator a hint pointer (default 0) so that it quicker finds a new memory chunk.

Regards,
Ovanes

初心 2024-08-04 01:30:14

存储迭代器应该没有问题,只需确保不在列表的副本上使用它们即可——迭代器绑定到列表的一个实例,并且不能在副本上使用。

也就是说,如果您这样做:

std::list<int>::iterator it = myList.begin ();
std::list<int> c = myList;

c.insert (it, ...); // Error

正如其他人指出的:当然,您也不应该通过删除指向的元素来使迭代器无效。

It should be no problem to store the iterators, just make sure you don't use them on a copy of the list -- an iterator is bound to one instance of the list, and cannot be used on a copy.

That is, if you do:

std::list<int>::iterator it = myList.begin ();
std::list<int> c = myList;

c.insert (it, ...); // Error

As noted by others: Of course, you should also not invalidate the iterator by removing the pointed-to element.

嗼ふ静 2024-08-04 01:29:40

是的,它会工作得很好。

由于许多其他答案都认为这是列表迭代器的特殊品质,因此我必须指出它可以与任何迭代器一起使用,包括向量迭代器。 如果向量被修改,向量迭代器就会失效,这一事实与将迭代器存储在另一个容器中是否合法的问题几乎没有关系——它。 当然,如果您执行任何使其无效的操作,迭代器就会失效,但这与迭代器是否存储在堆栈(或任何其他数据结构)中无关。

Yes, it'll work fine.

Since so many other answers go on about this being a special quality of list iterators, I have to point out that it'd work with any iterators, including vector ones. The fact that vector iterators get invalidated if the vector is modified is hardly relevant to a question of whether it is legal to store iterators in another container -- it is. Of course the iterator can get invalidated if you do anything that invalidates it, but that has nothing to do with whether or not the iterator is stored in a stack (or any other data structure).

傲鸠 2024-08-04 01:29:06

仅当列表被销毁或“指向”元素从列表中删除时,列表的迭代器才会失效。

Iterators to list are invalidated only if the list is destroyed or the "pointed" element is removed from the list.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文