简体   繁体   English

STL容器中的持久引用

[英]Persistant references in STL Containers

When using C++ STL containers, under what conditions must reference values be accessed? 使用C ++ STL容器时,必须在什么条件下访问引用值? For example are any references invalidated after the next function call to the container? 例如,在对容器的下一个函数调用之后,是否有任何引用无效?

{
std::vector<int> vector;
vector.push_back (1);
vector.push_back (2);
vector.push_back (3);

vector[0] = 10;       //modifies 0'th element

int& ref = vector[0];
ref = 10;             //modifies 0'th element

vector.push_back (4);
ref = 20;             //modifies 0'th element???

vector.clear ();
ref = 30;             //clearly obsurd
}

I understand that in most implementations of the stl this would work, but I'm interested in what the standard declaration requires. 据我所知,在stl的大多数实现中,这都可行,但我对标准声明的要求感兴趣。

--edit: Im interested becuase I wanted to try out the STXXL ( http://stxxl.sourceforge.net/ ) library for c++, but I realised that the references returned by the containers were not persistent over multiple reads, and hence not compatible without making changes (however superficial) to my existing stl code. --edit:我感兴趣因为我想尝试用于c ++的STXXL( http://stxxl.sourceforge.net/ )库,但我意识到容器返回的引用并不是多次读取的持久性,因此不是兼容,而不对我现有的stl代码进行更改(无论多么肤浅)。 An example: 一个例子:

{
std::vector<int> vector;
vector.push_back (1);
vector.push_back (2);


int& refA = vector[0];
int& refB = vector[1]; //refA is not gaurenteed to be valid anymore
}

I just wanted to know if this meant that STXXL containers where not 100% compatible, or indeed if I had been using STL containers in an unsafe/implementation dependant way the whole time. 我只是想知道这是否意味着STXXL容器不是100%兼容,或者确实如果我一直在以不安全/实现依赖的方式使用STL容器。

About inserting into vectors, the standard says in 23.2.4.3/1: 关于插入向量,标准在23.2.4.3/1中说:

[ insert() ] causes reallocation if the new size is greater than the old capacity. 如果新大小大于旧容量,[ insert() ]会导致重新分配。 If no reallocation happens, all the iterators and references before the insertion point remain valid. 如果没有重新分配,插入点之前的所有迭代器和引用仍然有效。

(Although this in fact this talks about insert() , Table 68 indicates that a.push_back(x) must be equivalent to a.insert(a.end(), x) for any vector a and value x .) This means that if you reserve() enough memory beforehand, then (and only then) iterators and references are guaranteed not to be invalidated when you insert() or push_back() more items. (虽然这实际上讨论了insert() ,但表68指出a.push_back(x)必须等同于任何向量a和值x a.insert(a.end(), x) 。)这意味着如果预先reserve()足够的内存,那么(并且只有这样)当insert()push_back()更多项时,保证迭代器和引用不会失效。

Regarding removing items, 23.2.4.3/3 says: 关于删除项目,23.2.4.3/3说:

[ erase() ] invalidates all the iterators and references after the point of the erase. [ erase() ]在擦除点之后使所有迭代器和引用无效。

According to Table 68 and Table 67 respectively, pop_back() and clear() are equivalent to appropriate calls to erase() . 根据表68和表67, pop_back()clear()等效于对erase()适当调用。

Some basic rules for vector: 矢量的一些基本规则:

  • Reallocation invalidates all references, pointers, and iterators for elements of the vector. 重新分配使向量元素的所有引用,指针和迭代器无效。
  • Insertions may invalidate references, pointers, and iterators. 插入可能使引用,指针和迭代器无效。
  • Inserting or removing elements invalidates references, pointers, and iterators that refer to the following elements. 插入或删除元素会使引用,引用和迭代器无效,这些引用,引用和迭代器引用以下元素。
  • If an insertion causes reallocation, it invalidates all references, iterators, and pointers. 如果插入导致重新分配,则会使所有引用,迭代器和指针无效。

我希望只有任何显式或隐式的resize()才能使引用无效(另请参阅max_sizecapacityreserve方法)。

Vector will invalidate its iterator and references when it reallocates, which depends upon its current capacity. Vector将在重新分配时使其迭代器和引用无效,这取决于其当前容量。 Although the above code might work in some cases, you shouldn't rely on this as the reference might be invalidated after the push_back(4) call. 虽然上面的代码在某些情况下可能有用,但是你不应该依赖它,因为在push_back(4)调用之后引用可能会失效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM