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

Mar*_*ner 29 c++ pointers stl stdvector

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

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

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
Run Code Online (Sandbox Code Playgroud)

情况怎么样,如果我用std::list而不是std::vector

Dum*_*der 25

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

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

  • @MartinStettner:§23.2.1.3保证当进入dequeue的迭代器失效时,指针和对元素的引用仍然有效:`deque中间的插入使所有迭代器和对deque元素的引用无效.在deque两端的插入使deque的所有迭代器无效,但对deque元素的引用的有效性没有影响. (7认同)
  • 我一直无法从标准中找到引用,它保证向量的容量不能缩小 - 这可能不是直接要求,而是其他要求的影响,因为算法的复杂性.您能否提供一个报价/理由,为什么标准要求矢量容量永远不会缩小? - 这是我所知道的所有实现的行为,但这与标准的保证不同. (3认同)
  • 答案应该颠倒,向量 -&gt; 否和列表 -&gt; 是,因为问题是“是否有任何保证这些指针仍然有效?” (2认同)

Sad*_*ido 9

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


Sjo*_*erd 6

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

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

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

  • 你确定吗?C++ 标准中是否有任何部分涵盖此声明?大多数时候它可能会以这种方式实现,但我需要某种保证...... (2认同)
  • @mxp:迭代器需要能够找到下一个元素.此功能需要迭代器中的其他信息,此附加信息可能无效. (2认同)