2017-09-19 14 views
2

を検索し、参照することによって返します。私はこれらの2つのパブリックメソッドを持つクラスを持っているSTLのmapで

私は、共通のfindを分離し、参照見つかっEntityCTCで返すためにこれらのメソッドをリファクタリングしたいと思いますが、私は「見つからないキー」の場合に処理する方法を見つけ出すことはできません。

EntityCTC& findEntity(const EntityCTCId id) { 
    auto it = entities.find(id); 
    if(it != entities.end()) 
     return it->second.state; 
    else 
     // ??? 
} 

のみを私が見つけた解決策は、この新しいメソッド内で例外をスローすることですが、それはsetEntityStateの中にtry-catchを使用して、更新と新しい挿入を区別することを意味します(例外管理を論理分岐として使用するのではなく、

他の方法を教えてください。

+2

私はあなたが過度にリファクタリングしているようです。 2つの異なる関数で同じマップ上でfind()を呼び出すのに問題は見られません。それぞれの目的が異なる場合です。 – Eli

+0

について:bool findEntity(const EntityCTCId id、EntityCTC&state)?さらに、idをエンティティから削除する可能性があるため、参照を返すことは適切な方法ではありません。 –

+0

getにはentities.atを、setにはStoryTellerの提案(またはoperator [] ')を使用すると何が問題になりますか?なぜ 'EntityCTCNotFound'が' std :: string'で構築され、 'EntityCTCId'では構築されないのですか? – Caleth

答えて

4

もう1つのアプローチは、APIをフルに活用することです。あなたには、emplaceに戻り値があります。それはstd::pair<iterator, bool>です。イテレータはキーの下のアイテムにアクセスするために使用でき、ブールは挿入が起こったか、キーがマップにすでに存在するかどうかを知らせることです。

void StateManager::setEntityState(const EntityCTCId id, const EntityCTCState state) { 
    auto status = entities.emplace(id, EntityCTC{id, state}); 
    if(!status.second) 
     status.first->second.state = state; 
} 

そして今、心配する一般的な機能はありません、あなたは2の代わりに関数の中で唯一のO(logN個)の操作を行います。

したがって、私はあなただけsetEntityStateを再書き込み示唆します。


補足説明の前に、価値を構成するためのコストについて心配するかもしれません。早すぎる最適化の一部ではありません。 APIを最大限に使用するためのもう1つの点は、マップに挿入されるペアを細かく構成する方法があることを知ることです。このように:

auto status = entities.emplace(std::piecewise_construct, 
           std::forward_as_tuple(id), 
           std::forward_as_tuple(id, state)); 
+0

しかし、今必要でない場合でも常に 'EntityCTC'を構築するオーバーヘッドがあります。 – nwp

+0

@nwp - 私ですか?コピーエリートは事です。 – StoryTeller

+0

はい。与えられた 'id'がすでに' entities'に存在する場合、元のコードはあなたが行っている間に 'EntityCTC'を作成しません。コピーelionはあなたをそれから救いません。 – nwp

関連する問題