使用std::list改进简单性

Improving simplicity with std::list

本文关键字:简单 list std 使用      更新时间:2023-10-16

有什么更好(更干净、更可读和/或更高效(的方法可以做到这一点:

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

你推荐什么?我主要需要将要放在篮子里的苹果的句柄,这样就可以从篮子里删除苹果,而不必搜索(例如,通过固定数组内的索引(。但是,Basket需要在进程中分配和解除分配内存。

另一种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);

通过这种方式,您可以获得更好的性能,并且对接口几乎没有更改,因为迭代器在大多数情况下的行为就像指针。

还可以看看以下内容:是否应该弃用std::list?

请注意,要使两个解决方案都工作,Basket容器必须是std::list

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!(