for (Shape *i : shapes) {
for (Shape *j : shapes) {
if (i != j) {
if (check(i,j)){
shapes.erase(remove(shapes.begin(), shapes.end(), i), shapes.end());
这会导致错误,因为即使我不存在它也会继续进行迭代,我的问题是如何干净地执行此操作?目前我收到错误"矢量迭代器不可递增"
我可以退出第二个循环并继续第一个循环吗?
答案 0 :(得分:2)
当你通过范围循环迭代时,你不能从向量中删除元素,因为在内部它使用了无效的迭代器。这应该有效:
auto end = shapes.end();
for( auto it = shapes.begin(); it != end; ++it ) {
end = shapes.erase( std::remove_if( std::next( it ), shapes.end(), [it]( Shape *s ) {
return check( *it, s );
}, shapes.end() );
}
请注意,此代码比您的代码更有效,但它假定为check( s1, s2 ) == check( s2, s1 )
,如果您可以更改check()
函数以执行严格的排序比较,而不是等效,那么您就可以使用std::sort
和std::unique
更有效。
答案 1 :(得分:1)
在这种情况下,您不能使用range-for循环。而是使用带迭代器的标准循环:
for(auto iter = shapes.begin(); iter!= shapes.end(); iter ++)
答案 2 :(得分:1)
在使用基于范围的shapes
循环时,您无法修改for
元素的位置。范围循环在内部使用迭代器,并且擦除vector
元素使现有迭代器无效。
尝试更像这样的东西:
auto iter = shapes.begin();
auto end = shapes.end();
while (iter != end) {
auto iter2 = shapes.begin();
bool erased = false;
while (iter2 != end) {
if ((iter != iter2) && check(*iter, *iter2)) {
iter = shapes.erase(iter);
end = shapes.end();
erased = true;
break;
}
++iter2;
}
if (!erased)
++iter;
}
或者,也许更像这样的东西也可以起作用:
shapes.erase(
std::remove_if(shapes.begin(), shapes.end(),
[shapes&](Shape *i) {
for (Shape *j : shapes) {
if ((i != j) && check(i, j)) {
return true;
}
}
return false;
}
),
shapes.end()
);