2013-05-10 2 views
4

Какие лучше (чище, читаемых и/или эффективные) способы сделать это:Повышение простоты с станд :: Список

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 

Что бы вы порекомендовали? Я прежде всего нуждаюсь в ручках для яблок, которые я буду размещать внутри корзины, чтобы удалить яблоки из корзины без поиска (например, по индексу внутри фиксированного массива). Тем не менее, корзине необходимо выделять и освобождать память в процессе.

+5

Не использовать 'std :: list' ... – Mehrdad

+2

Звучит как вопрос для http://coderview.stackexchange.com/ –

+1

Правило большого пальца:' std :: list' всегда является неправильным контейнером –

ответ

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.

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

Смежные вопросы