2012-03-29 20 views
1

以下の状況で、リストから画面を削除するにはどうすればよいですか?std :: listからオブジェクトを削除する

class ScreenManager { 

    list<GameScreen> screens; 

    void removeScreen(GameScreen & screen) { 
     //screens.remove(screen); // won't work 
     //screens.erase(remove(screens.begin(), screens.end(), screen), screens.end()); // won't work either 
    } 
} 
+0

なぜ機能しませんか? – vmpstr

+5

'remove'が動作します。もしそうでなければ、あなたは私たちに十分なことを話していません。 –

+0

詳細を教えてください。より多くのコードを提供できますか? – ManiP

答えて

2

list :: findを使用して、実際に削除したい画面にイテレータを配置します。その後、イテレータを渡してremoveを使用します。

+2

'remove'はイテレータを使用しません。つまり、' erase'を意味します。しかし、 'find'に続く' find'は 'remove'とまったく同じです。だから誰がこれをアップしたのでしょうか? –

2

std :: listの消去メソッドは、削除するイテレータをとります。ですから、一度イテレータをスクリーンに取得したら、それをスクリーンに渡すだけです。

つまり、実行したいscreens.erase(std::find(screens.begin(), screens.end(), screen));これは、演算子==が値クラスで正しく定義されている場合にのみ機能します。

多くのものを削除する予定がある場合は、std :: listの代わりにstd :: mapのようなものを使用することをお勧めします(リスト内の画面を参照するとO(n)になります)

+3

実際、私のスニペットが動作するときは、removeも動作するはずです...だから、あなたの問題はおそらくoperator ==をオーバーライドする必要があるでしょう。 –

+0

私はオペレーターと何をする必要があるのか​​、またその理由を説明できますか? – Ben

+0

ヨハネス・エスの答えがここにあります。基本的には、リスト内のどのオブジェクトが探しているのかを知る必要があります。C++では、(operator ==をオーバーライドすることによって)その方法を教えない限り、それを行う方法はありません。もう1つの選択肢は、リストを持って、すべてのオブジェクトを「新しい」状態にして、ポインタをコピーするだけです。その後、remove/findはポインタの等価性を使用します。しかし、そこにも多くの問題があります:-) –

11

std::remove(またはご使用の場合はstd::list::remove)は、比較演算子(operator==)を使用して、コンテナから削除する必要があるオブジェクトを検索/識別します。

ユーザ定義タイプGameScreenを使用しているため、クラスにはoperator==を指定する必要があります。

bool operator==(const GameScreen& other) const { 
    // do whatever you need to determine whether 
    // `GameScreen` instance `other` is equal (in value) 
    // to `this` instance of `GameScreen` 
} 

その後、screens.remove(screen);は動作します:だから、あなたのクラスであなたが実装する必要があります。

+0

@Benこれで問題は解決しましたか? –

関連する問題