使用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容器。
答案 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_size
,capacity
和reserve
方法。
答案 3 :(得分:1)
Vector会在重新分配时使其迭代器和引用无效,这取决于其当前容量。虽然上面的代码在某些情况下可能会起作用,但是你不应该依赖它,因为在push_back(4)调用之后引用可能会失效。