矢量迭代器不兼容

时间:2011-12-07 19:53:22

标签: c++ stl vector

我有一个带有std :: vector数据成员的类,例如

class foo{
public:

const std::vector<int> getVec(){return myVec;} //other stuff omitted

private:
std::vector<int> myVec;

};

现在在我的主要代码的某些部分,我试图迭代这样的向量:

std::vector<int>::const_iterator i = myFoo.getVec().begin();
while( i != myFoo.getVec().end())
{
   //do stuff
   ++i;
}

当我到达这个循环时,我得到上述错误。

10 个答案:

答案 0 :(得分:70)

你得到这个的原因是,迭代器来自myVec的两个(或更多)不同的副本。每次调用myFoo.getVec()时,您都会返回向量的副本。所以迭代器是不兼容的

一些解决方案:

将const引用返回到std::vector<int>

const std::vector<int> & getVec(){return myVec;} //other stuff omitted

另一种解决方案,可能更可取的方法是获取向量的本地副本并使用它来获取迭代器:

const std::vector<int> myCopy = myFoo.getVec();
std::vector<int>::const_iterator i = myCopy.begin();
while(i != myCopy.end())
{
  //do stuff
  ++i;
}

另外+1代表using namespace std;

答案 1 :(得分:10)

您正在返回该矢量的副本。因为您按值返回 - 您对begin()和end()的调用是针对完全不同的向量。你需要返回一个const&amp;它。

const std::vector<int> &getVec(){return myVec;}

虽然我会稍微改变一下。我让这个课程有点像标准容器

class Data
{
   public:
      typedef std::vector<int>::const_iterator const_iterator;

      const_iterator begin() const { return myVec.begin(); }
      const_iterator end() const { return myVec.end(); }
};

Data::const_iterator i=myFoo.begin();

while(i != myFoo.end())
{
//
}

答案 2 :(得分:3)

MSVC STL调试断言的另一个原因&#34;矢量迭代器不兼容&#34;正在一个无效的迭代器上运行。

即。 v.erase(i),然后比较i != v.end()删除无效i,因此无法用于比较。

答案 3 :(得分:2)

问题是你总是返回另一个向量副本。使用参考:

const std::vector<int>& getVec(){return myVec;} //other stuff omitted

答案 4 :(得分:2)

好吧,我不认为矢量副本可能是唯一的原因,这似乎对我来说过于明显。

在我的情况下,我发现损坏的堆栈,堆,无条件的更改也可能导致此失败,并且实际上隐藏了潜在的原因。在我的情况下,我改为使用索引器迭代并找到根本原因。

答案 5 :(得分:2)

此断言可以触发的另一个原因是,如果您将“foo”分配为“malloc”而不是“new”,则有效地跳过构造函数。

在C ++中从头开发的项目不太可能发生,但是当将普通C代码转换为C ++(用stl-vector替换某些结构中的静态数组[])时,您可能根本没有意识到动态实例所谓的struct(以及里面的成员)不会调用它们的构造函数 - 除非你也将'malloc'改为'new'。

答案 6 :(得分:1)

您正在制作成员矢量的常量副本,而不是访问成员矢量。

改变这个:

const std::vector<int> getVec(){return myVec;} //other stuff omitted

到此:

const std::vector<int> & getVec(){return myVec;} //other stuff omitted

更深入一点,你从这句话得到的迭代器:

std::vector<int>::const_iterator i = myFoo.getVec().begin();

是向量临时副本的迭代器,在该语句执行后消失,使迭代器无效。

答案 7 :(得分:1)

更改

const std::vector<int> getVec(){return myVec;}

const std::vector<int>& getVec(){return myVec;}

答案 8 :(得分:0)

你的getVec()函数返回成员向量的深层副本,因此你要做的两个getVec()调用来检索迭代器获取不同容器的迭代器。也就是说,你不能从一个单独的getVec()。begin()迭代器到达getVec()。end()而不调用未定义的行为。

您可以通过两种方式解决此问题:

1)让getVec返回一个const引用(即const std :: vector&amp;)(首选)或......

2)用一个替换两个getVec()调用,并将结果保存到std :: vector变量。然后,将该变量用于begin()和end()两个调用。 E.g:

std::vector<int> v = myFoo.getVec();
std::vector<int>::const_iterator b = v.begin();
std::vector<int>::const_iterator e = v.end();

答案 9 :(得分:-1)

因为您按值返回 - 您对begin()和end()的调用是针对完全不同的向量。你需要返回一个const&amp;它呢