簡體   English   中英

在STL地圖中查找並通過引用返回

[英]Find and return by reference in STL map

我有一個使用這兩個公共方法的類:

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

EntityCTCState StateManager::getEntityState(const EntityCTCId id) const {
    auto it = entities.find(id);
    if(it != entities.end())
        return it->second.state;

    std::stringstream ss;
    ss << "Entity CTC [" << id << "] NOT found!";
    throw EntityCTCNotFound{ss.str()};
}

其中entitiesstd::map<EntityCTCId, EntityCTC>

我想重構這些方法以隔離常見的find並通過引用找到的EntityCTC返回,但是我無法弄清楚如何處理“找不到密鑰”的情況:

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

我發現的唯一解決方案是將異常拋出該新方法內,但這意味着在setEntityState使用try-catch來區分更新和新插入(並且我讀到異常管理不應用作邏輯分支,而應僅用於錯誤管理)。

您能建議我其他方法嗎?

另一種方法是充分利用API。 如您所見, emplace具有返回值。 這是一個std::pair<iterator, bool> 迭代器可用於訪問鍵下的項目,布爾值用於通知您是否發生了插入或鍵是否已存在於映射中。

因此,我建議您只重寫setEntityState

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

現在,無需擔心通用功能,並且在該函數中只執行一個O(logN)操作,而不是兩個。


附錄,因為您可能會擔心構建值的成本,而不是過早優化的一部分。 關於充分利用API的另一點是要知道有一種方法可以分段構造插入映射的對。 像這樣:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM