有哪些更好(更干净,更易读和/或更有效)的方法:
std::list<Fruit*> Apples;
std::list<Fruit> Basket;
for (std::list<Fruit*>::iterator niApple(Apples.begin());
niApple != Apples.end(); niApple++) {
for (std::list<Fruit>::iterator niBasket(Basket.begin());
niBasket != Basket.end(); niBasket++) {
if (&(*niBasket) == *niApple) {
Basket.erase(niBasket);
break;
}
} // loop
} // loop
你会推荐什么?我主要需要苹果的手柄,我将放在篮子内,所以要从篮子中移除苹果,而不必搜索(例如,通过固定数组内的索引)。但是,篮子需要在过程中分配和释放内存。
答案 0 :(得分:7)
另一种C ++ 11方式:
list<Fruit*> Apples;
list<Fruit> Basket;
Basket.remove_if([](const Fruit& fruit) {
return any_of(Apples.begin(), Apples.end(), [](Fruit* apple) {
return &fruit == apple;
});
});
现在更改第一个容器以将迭代器保存到第二个容器:
list<list<Fruit>::iterator> Apples;
list<Fruit> Basket;
for (auto apple : Apples)
Basket.erase(apple);
通过这种方式,您可以获得更好的性能,并且对接口进行很少或没有更改,因为在大多数情况下迭代器的行为类似于指针。
另请看一下:Should std::list be deprecated?
请注意,要使两个解决方案都有效,Basket
容器必须为std::list
。
答案 1 :(得分:4)
std::list<Fruit*> Apples;
std::list<Fruit> Basket;
auto is_apple = [](const Fruit& frt) {
for(auto apl: Apples) { //for each Apple pointer
if (apl== &frt) //if it points at the current fruit
return true; //then it's one of the apples
}
return false; //otherwise it's not one of the apples
};
Basket.remove_if(is_apple);
这对我来说似乎更简单。 (Hooray C ++ 11!)