Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Improving simplicity with std::list

What are some better (cleaner, more readable and/or efficient) ways of doing this:

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

What would you recommend? I primarly need handles to the Apples which i'll be placing inside the Basket, so to remove the Apples form the Basket without having to search (e.g.. by index inside fixed array). However, the Basket needs to be allocating and deallocating the memory in the process.

like image 889
8-bitButterfly Avatar asked Dec 20 '22 05:12

8-bitButterfly


1 Answers

Another C++11 way:

list<Fruit*> Apples;
list<Fruit>  Basket;

Basket.remove_if([](const Fruit& fruit) {
    return any_of(Apples.begin(), Apples.end(), [](Fruit* apple) {
        return &fruit == apple;
    });
});

Now changing the first container to hold iterators to the second one:

list<list<Fruit>::iterator> Apples;
list<Fruit>  Basket;

for (auto apple : Apples)
    Basket.erase(apple);

This way you get better performance and little or no change to your interface, as iterators behave like pointers in most cases.

Also take a look at this: Should std::list be deprecated?

Note that for both solutions to work, the Basket container must be std::list.

like image 176
Guilherme Bernal Avatar answered Dec 24 '22 00:12

Guilherme Bernal