[英]Vector Iterators Incompatible
我有一个带有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;
}
我到达这个循环的那一刻,我得到了上述错误。
你得到这个的原因是,迭代器来自myVec的两个(或更多)不同的副本。 每次调用myFoo.getVec()
,都会返回向量的副本。 所以迭代器是不兼容的 。
一些解决方案
返回对std::vector<int>
的const引用:
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;
您正在返回该向量的副本。 因为您按值返回 - 您对begin()和end()的调用是针对完全不同的向量。 你需要返回一个const&它。
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())
{
//
}
MSVC STL调试断言“矢量迭代器不兼容”的另一个原因是在无效的迭代器上运行。
即v.erase(i)
,然后比较i != v.end()
擦除使i
无效,因此它不能用于比较。
好吧,我不认为矢量副本可能是唯一的原因,这对我来说似乎过于苛刻。
在我的情况下,我只是发现损坏的堆栈,堆,无条件的更改也可能导致此失败,并且实际上隐藏了潜在的原因。 在我的情况下,我改为使用索引器迭代并找到根本原因。
这个断言可以触发的另一个原因是你是否将“foo”分配给'malloc'而不是'new',从而有效地跳过了构造函数。
在C ++中从头开发的项目不太可能发生,但是当将普通C代码转换为C ++(用某个stl-vector替换某个结构中的静态数组[])时,您可能根本没有意识到所述结构的动态实例(并且其中的成员不会被调用它们的构造函数 - 除非你也将'malloc'改为'new'。
问题是你总是返回另一个向量的副本。 使用参考:
const std::vector<int>& getVec(){return myVec;} //other stuff omitted
您正在创建成员向量的常量副本,而不是访问成员向量。
改变这个:
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();
是向量的临时副本的迭代器,它在该语句执行后消失,使迭代器无效。
更改
const std::vector<int> getVec(){return myVec;}
至
const std::vector<int>& getVec(){return myVec;}
你的getVec()函数返回成员向量的深层副本,因此你要做的两个getVec()调用来检索迭代器获取不同容器的迭代器。 也就是说,您无法从单独的getVec()。begin()迭代器到达getVec()。end()而不调用未定义的行为。
您可以通过两种方式解决此问题:
1)让getVec返回一个const引用(即const std :: vector&)(首选)或......
2)用一个替换两个getVec()调用,并将结果保存到std :: vector变量。 然后,将该变量用于begin()和end()两个调用。 例如:
std::vector<int> v = myFoo.getVec();
std::vector<int>::const_iterator b = v.begin();
std::vector<int>::const_iterator e = v.end();
因为您按值返回 - 您对begin()和end()的调用是针对完全不同的向量。 你需要返回一个const&它
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.