C++ 指向 std::vector 和 std::list 元素的指针

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3287801/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 12:33:19  来源:igfitidea点击:

Pointers to elements of std::vector and std::list

c++stlpointersstdvector

提问by MartinStettner

I'm having a std::vectorwith elements of some class ClassA. Additionally I want to create an index using a std::map<key,ClassA*>which maps some key value to pointers to elements contained in the vector.

我有std::vector一些类的元素ClassA。此外,我想使用 a 创建一个索引std::map<key,ClassA*>,它将一些键值映射到指向向量中包含的元素的指针。

Is there any guarantee that these pointers remain valid (and point to the same object) when elements are addedat the end of the vector (not inserted). I.e, would the following code be correct:

当元素添加到向量的末尾(未插入)时,是否可以保证这些指针保持有效(并指向同一个对象)。即,以下代码是否正确:

std::vector<ClassA> storage;
std::map<int, ClassA*> map;

for (int i=0; i<10000; ++i) {
  storage.push_back(ClassA());
  map.insert(std::make_pair(storage.back().getKey(), &(storage.back()));
}
// map contains only valid pointers to the 'correct' elements of storage

How is the situation, if I use std::listinstead of std::vector?

如果我使用std::list而不是,情况如何std::vector

采纳答案by DumbCoder

Vectors - No. Because the capacity of vectors never shrinks, it is guaranteed that references, pointers, and iterators remain valid even when elements are deleted or changed, provided they refer to a position before the manipulated elements. However, insertions may invalidate references, pointers, and iterators.

向量 - 不会。因为向量的容量永远不会缩小,所以即使删除或更改元素,也可以保证引用、指针和迭代器保持有效,只要它们引用被操作元素之前的位置。但是,插入可能会使引用、指针和迭代器无效。

Lists - Yes, inserting and deleting elements does not invalidate pointers, references, and iterators to other elements

列表 - 是的,插入和删除元素不会使指向其他元素的指针、引用和迭代器失效

回答by SadSido

As far as I understand, there is no such guarantee. Adding elements to the vector will cause elements re-allocation, thus invalidating all your pointers in the map.

据我了解,没有这样的保证。向向量添加元素将导致元素重新分配,从而使地图中的所有指针无效。

回答by Sjoerd

Use std::deque! Pointers to the elements are stable when only push_back()is used.

使用std::deque!指向元素的指针在仅push_back()使用时是稳定的。

Note: Iterators to elements may be invalidated! Pointers to elements won't.

注意:元素的迭代器可能会失效!指向元素的指针不会。

Edit: this answer explains the details why: C++ deque's iterator invalidated after push_front()

编辑:这个答案解释了详细原因:C++ deque 的迭代器在 push_front() 之后失效

回答by sbi

I'm not sure whether it's guaranteed, but in practice storage.reserve(needed_size)should make sure no reallocations occur.

我不确定它是否有保证,但在实践中storage.reserve(needed_size)应该确保不会发生重新分配。

But why don't you store indexes?
It's easy to convert indexes to iterators by adding them to the begin iterator (storage.begin()+idx) and it's easy to turn any iterator into a pointer by first dereferencing it, and then taking its address (&*(storage.begin()+idx)).

但是为什么不存储索引呢?
通过将索引添加到开始迭代器 ( storage.begin()+idx) 可以很容易地将索引转换为迭代器,并且可以通过首先取消引用它,然后获取其地址 ( &*(storage.begin()+idx))来轻松将任何迭代器转换为指针。

回答by David Rodríguez - dribeas

From one of the comments to another answer, it seems as if all that you want is centralize (ease) memory management. If that is really the case, you should consider using prepackaged solutions like the boost pointer containerlibrary and keep your own code as simple as possible.

从一个评论到另一个答案,似乎您想要的只是集中(轻松)内存管理。如果情况确实如此,您应该考虑使用预打包的解决方案,例如boost 指针容器库,并让您自己的代码尽可能简单。

In particular, take a look at ptr_map

特别是,看看 ptr_map

回答by Tom

Just make them both store pointers an explicitly delete the objects when you don't need them.

只需让它们都存储指针,并在不需要它们时显式删除对象。

std::vector<ClassA*> storage;
std::map<int, ClassA*> map;

for (int i=0; i<10000; ++i) {
  ClassA* a = new ClassA()
? storage.push_back(a)
? map.insert(std::make_pair(a->getKey(), a))
}
// map contains only valid pointers to the 'correct' elements of storage

回答by Nakul Vaidya

  1. for vectors no.
  2. for lists yes. how? iterator works as a pointer to a particular node in the list. so you can assign values to any struct like:

    list mylist;

    pair< list::iterator ,int > temp;

    temp = make_pair( mylist.begin() , x );

  1. 对于载体没有。
  2. 对于列表是的。如何?迭代器用作指向列表中特定节点的指针。因此您可以为任何结构赋值,例如:

    列出 mylist;

    pair< list::iterator ,int > temp;

    temp = make_pair( mylist.begin() , x );