我需要编写一个函数,将std::vector<std::shared_ptr<Shape >> shapes_
的每个元素与每个其他元素进行比较,确定形状是否重叠,然后删除其中一个重叠形状(如果是这样)。这是我目前所拥有的:
class Shape {
public:
...
virtual bool overlaps(const std::shared_ptr<Shape>&) const = 0;
...
};
class Square : public Shape { ... } ;
class Circle : public Shape { ... } ;
利用这些课程:
std::vector<shared_ptr<Shape>> shapes_;
// ... some code populates the array
for (auto& shape : shapes_) {
// Compare to every other shape
for (unsigned long j = 0; j < shapes_.size(); j++) {
// If they overlap and they aren't the same shape
if (shape->overlaps(shapes_.at(j)) && shape!=shapes_.at(j)) {
shapes_.erase(shapes_.begin() + j);
}
}
}
然而,我一直在遇到问题,我在迭代一个null(已移除)元素,或超出数组的末尾或其他东西。我一直在以这种方式重新配置它,但是其中一个问题不断出现。
在将一个向量的每个元素与其他元素进行比较时,处理问题的最明智,最干净的方法是什么,并且在此过程中有时会删除一些元素?
此外,如果我想打印一些有关找到的重叠信息以及删除的形状,该怎么办?
答案 0 :(得分:2)
您可以使用erase-remove惯用语:
auto it = vec.begin();
auto end = vec.end();
while( std::distance( it, end ) > 1 ) {
auto condition = [shape=*it]( const auto &other ) { return shape->overlaps( other ); };
end = std::remove_if( ++it, end, condition );
}
vec.erase( end, vec.end() );
这个lambda语法需要C ++ 14,但如果需要,可以很容易地修改它以使用C ++ 11(例如,在lambda之前引入临时变量shape
,或者通过以下方式捕获it
值不参考)。