STL容器中的持久引用

时间:2009-09-07 05:18:26

标签: c++ stl

使用C ++ STL容器时,必须在什么条件下访问引用值? 例如,在对容器进行下一次函数调用后,是否有任何引用无效?

{
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
}

据我所知,在stl的大多数实现中,这都可行,但我对标准声明的要求感兴趣。

- 编辑: 我感兴趣,因为我想尝试用于c ++的STXXL(http://stxxl.sourceforge.net/)库,但我意识到容器返回的引用并不是多次读取的持久性,因此如果不进行更改(无论多么肤浅)就不兼容我现有的stl代码。一个例子:

{
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
}

我只是想知道这是否意味着STXXL容器不是100%兼容的,或者确实如果我一直在以不安全/实现依赖的方式使用STL容器。

4 个答案:

答案 0 :(得分:12)

关于插入向量,标准在23.2.4.3/1中说:

  

[insert()]会导致重新分配   新尺寸大于旧尺寸   容量。如果没有重新分配,   所有迭代器和引用   在插入点之前保留   有效的。

(虽然这实际上涉及insert(),但表68指出a.push_back(x)对于任何向量a.insert(a.end(), x)和值a必须等同于x 。)这意味着如果事先reserve()有足够的内存,那么当你insert()push_back()项更多时,保证迭代器和引用不会失效。

关于删除项目,23.2.4.3 / 3说:

  

[erase()]使所有人失效   之后的迭代器和引用   擦除点。

根据表68和表67,pop_back()clear()相当于对erase()的适当调用。

答案 1 :(得分:8)

vector的一些基本规则:

  • 重新分配使所有人无效 引用,指针和迭代器 对于矢量元素。
  • 插入可能使参考无效, 指针和迭代器。
  • 插入或移除元素 使引用,指针和 引用以下内容的迭代器 元件。
  • 如果插入导致重新分配, 它使所有引用无效, 迭代器和指针。

答案 2 :(得分:1)

我希望只有明确或隐含的resize()引用才能使引用无效(另请参阅max_sizecapacityreserve方法。

答案 3 :(得分:1)

Vector会在重新分配时使其迭代器和引用无效,这取决于其当前容量。虽然上面的代码在某些情况下可能会起作用,但是你不应该依赖它,因为在push_back(4)调用之后引用可能会失效。