使用std :: list提高简洁性

时间:2013-05-10 00:37:05

标签: c++ performance

有哪些更好(更干净,更易读和/或更有效)的方法:

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

你会推荐什么?我主要需要苹果的手柄,我将放在篮子内,所以要从篮子中移除苹果,而不必搜索(例如,通过固定数组内的索引)。但是,篮子需要在过程中分配和释放内存。

2 个答案:

答案 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!)