在STL地图中通过参考查找并返回

Find and return by reference in STL map

本文关键字:参考 查找 返回 STL 地图      更新时间:2023-10-16

我有一个与这两种公共方法的类:

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