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

あなたは何をお勧めします?主に、バスケット内に配置するリンゴへのハンドルが必要なので、検索せずにバスケットからリンゴを削除します(たとえば、固定配列内のインデックスによって)。ただし、バスケットはプロセス内でメモリの割り当てと割り当て解除を行う必要があります。

4

2 に答える 2

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;
    });
});

次に、イテレータを保持する最初のコンテナを 2 番目のコンテナに変更します。

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

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

ほとんどの場合、反復子はポインターのように動作するため、このようにして、パフォーマンスが向上し、インターフェイスにほとんどまたはまったく変更が加えられません。

こちらもご覧ください: Should std::list be deprecated?

両方のソリューションが機能するには、Basketコンテナがstd::list.

于 2013-05-10T01:55:26.577 に答える
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);

それは私には簡単に思えます。(万歳 C++11!)

于 2013-05-10T00:47:14.670 に答える