我迷路了:除非在++之前有一个函数调用(Z_UB-> set()),否则std :: string向量的迭代器工作得很好。这是代码:
std::vector< std::string >::iterator it = g_SPP.scenarios->getVector().begin();
std::cout << "begin of vector: " << *it << std::endl;
Z_UB->set("s1", "scn2", 350);
it++;
std::cout << "second of vector: " << *it << std::endl;
创建以下输出
begin of vector: scn1
但是,如果我像这样移动函数调用:
std::vector< std::string >::iterator it = g_SPP.scenarios->getVector().begin();
std::cout << "begin of vector: " << *it << std::endl;
it++;
std::cout << "second of vector: " << *it << std::endl;
Z_UB->set("s1", "scn2", 350);
结果如下,这是预期的行为:
begin of vector: scn1
second of vector: scn2
在Z_UB-&gt; set()函数内部,除了调用本身之外什么都没有留下:
void Parameter::set( std::string _i, std::string _j, float value) {
//int i = indexSets[0]->backIndex(_i);
//int j = indexSets[1]->backIndex(_j);
//data2D[0][0] = value;
}
因此,如果在创建迭代器后调用Z_UB-&gt; set()函数,访问它将使程序崩溃。有没有什么重要的我错过了迭代器?
答案 0 :(得分:2)
如果g_SPP
是全局变量,则任何变异操作都会使其上的迭代器失效。
更新 - 这是1998 ISO / ANSI规范:
如果需要分配,以下内容将引用序列元素的所有引用,迭代器和指针无效。如果当前capacity()
小于目标矢量大小,则需要进行分配。
void reserve(size_type n)
iterator insert(iterator position, const T& x)
,void insert(iterator position, size_type n, const T& x)
,void insert(iterator position, InputIterator first, InputIterator last)
和Erasure使所有引用,迭代器和指针在初始擦除元素的位置之后引用元素无效。
iterator erase(iterator position)
iterator erase(iterator first, iterator second)
调整向量大小相当于调用insert
或erase
。根据23.2.4.2/6:resize(sz, c=value_type())
具有与以下相同的效果:
if (sz > size())
insert(end(), sz - size(), c);
else if (sz < size())
erase(begin() + sz, end());
else
;
答案 1 :(得分:2)
几种可能性:
it
对{ {1}} g_SPP.scenarios->getVector().end()
没有按照您的想法行事。它是一个多态类吗? Z_UB->set
是虚拟的吗? set
运算符是否已重载?答案 2 :(得分:1)
如果在迭代时添加或删除元素,如果向量需要在内部调整自身大小,添加元素时,std::vector<T>::iterator
将失效。
答案 3 :(得分:1)
.getVector()返回了矢量的副本。将迭代器与完全不同的对象的迭代器的终点进行比较是没有意义的。返回引用解决了问题。
@Xeo还指出了一个更好的解释:从这样的副本创建迭代器时:
std::vector< std::string >::iterator it = g_SPP.scenarios->getVector().begin();
立即销毁副本,从而使刚创建的迭代器无效。所以迭代器不应该首先返回第一个元素,但我只能猜测这是隐藏在编译器实现中的。