Improving simplicity with std :: list

What are better (cleaner, more readable and / or efficient) ways to do 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? First of all, I need apple handles, which I will place inside the basket to remove apples from the basket without searching (for example, by index inside a fixed array). However, the recycle bin needs to allocate and free memory in the process.

+4
source share
2 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 change the first container to save the iterators to the second:

 list<list<Fruit>::iterator> Apples; list<Fruit> Basket; for (auto apple : Apples) Basket.erase(apple); 

This way you get better performance and don't change your interface very little or no, since 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 .

+7
source
 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 one of the apples } return false; //otherwise it not one of the apples }; Basket.remove_if(is_apple); 

It seems easier to me. (Hooray C ++ 11!)

+4
source

Source: https://habr.com/ru/post/1480015/


All Articles