C++;迭代器问题 我正在使用C++中的迭代器,我遇到了一些麻烦。它在interIterator++行的表达式(this->_Has_container())上显示“调试断言失败”。 距离列表是一个向量。我做错了什么 vector< vector<DistanceNode> >::iterator externIterator = distanceList.begin(); while (externIterator != distanceList.end()) { vector<DistanceNode>::iterator interIterator = externIterator->begin(); while (interIterator != externIterator->end()){ if (interIterator->getReference() == tmp){ //remove element pointed by interIterator externIterator->erase(interIterator); } // if interIterator++; } // while externIterator++; } // while vector::迭代器外部监视器=距离列表。开始(); while(exterMonitor!=distanceList.end()){ 向量::迭代器interIterator=externIterator->begin(); while(interIterator!=externIterator->end()){ if(interIterator->getReference()==tmp){ //删除迭代器指向的元素 外部监视器->擦除(迭代器); }//如果 interIterator++; }//而 外部监视器++; }//而
向量的C++;迭代器问题 我正在使用C++中的迭代器,我遇到了一些麻烦。它在interIterator++行的表达式(this->_Has_container())上显示“调试断言失败”。 距离列表是一个向量。我做错了什么 vector< vector<DistanceNode> >::iterator externIterator = distanceList.begin(); while (externIterator != distanceList.end()) { vector<DistanceNode>::iterator interIterator = externIterator->begin(); while (interIterator != externIterator->end()){ if (interIterator->getReference() == tmp){ //remove element pointed by interIterator externIterator->erase(interIterator); } // if interIterator++; } // while externIterator++; } // while vector::迭代器外部监视器=距离列表。开始(); while(exterMonitor!=distanceList.end()){ 向量::迭代器interIterator=externIterator->begin(); while(interIterator!=externIterator->end()){ if(interIterator->getReference()==tmp){ //删除迭代器指向的元素 外部监视器->擦除(迭代器); }//如果 interIterator++; }//而 外部监视器++; }//而,c++,iterator,vector,C++,Iterator,Vector,向量的擦除()将新的迭代器返回到下一个元素。所有迭代器都指向已擦除的元素,并指向失效后的元素。但是,您的循环忽略了这一点,并继续使用interIterator 您的代码应该如下所示: if (condition) interIterator = externIterator->erase(interIterator); else ++interIterator; // (generally better practice to use pre-increment) 在序
擦除()
将新的迭代器返回到下一个元素。所有迭代器都指向已擦除的元素,并指向失效后的元素。但是,您的循环忽略了这一点,并继续使用interIterator
您的代码应该如下所示:
if (condition)
interIterator = externIterator->erase(interIterator);
else
++interIterator; // (generally better practice to use pre-increment)
在序列容器上进行迭代时,不能从序列容器中删除元素,至少不能以您现在的方式进行,因为调用
erase
会使迭代器无效。您应该将erase
中的返回值指定给迭代器并抑制增量:
while (interIterator != externIterator->end()){
if (interIterator->getReference() == tmp){
interIterator = externIterator->erase(interIterator);
} else {
++interIterator;
}
}
另外,当预增量(++i)可以使用时,切勿使用后增量(i++)。我将冒昧地重写代码:
class ByReference: public std::unary_function<bool, DistanceNode>
{
public:
explicit ByReference(const Reference& r): mReference(r) {}
bool operator()(const DistanceNode& node) const
{
return node.getReference() == r;
}
private:
Reference mReference;
};
typedef std::vector< std::vector< DistanceNode > >::iterator iterator_t;
for (iterator_t it = dl.begin(), end = dl.end(); it != end; ++it)
{
it->erase(
std::remove_if(it->begin(), it->end(), ByReference(tmp)),
it->end()
);
}
正如您所看到的,我们再也看不到任何迭代器递增/取消引用的情况发生了,它都被封装在专用的算法中,以确保一切都得到适当的处理
我承认语法看起来很奇怪,但我想这是因为我们还不习惯它。这不是错误的原因,但你应该使用pre-increment来提升迭代器-++interIterator。这并不影响性能,它已经被大多数编译器优化了。谢谢,这对我自己的问题有很大帮助。
std::for_each(distanceList.begin(), distanceList.end(),
[const& tmp](std::vector<DistanceNode>& vec)
{
vec.erase(
std::remove_if(vec.begin(), vec.end(),
[const& tmp](const DistanceNode& dn) { return dn.getReference() == tmp; }
),
vec.end()
);
}
);