如何安全从STL map或unordered_map取值?为何无类似C# TryGetValue的方法?
如何安全地从STL map或unordered_map中按键取值?
最直观的解决方案是:
const auto it = map.find(key); if (it != std::end(map)) { myValue = std::get<1>(*it); } else { // 无对应键的处理逻辑... }
这段代码的使用频率极高,但STL为何没有提供类似C#中TryGetValue的辅助方法呢?STL已经包含了大量工具函数,比如std::get<>()、std::make_...<>()、std::begin/end()等,照理说std::try_get()完全符合STL的设计逻辑。
我们可以自行实现这样的辅助函数:
namespace std { template<class Key, class T, class Hash = hash<Key>, class KeyEqual = equal_to<Key>, class Allocator = allocator<pair<const Key, T>>> bool try_get(const unordered_map<Key, T, Hash, KeyEqual, Allocator>& map, const Key& key, T* value) { const auto it = map.find(key); const bool res = it != end(map); if (res && value != nullptr) { *value = get<1>(*it); } return res; } template<class Key, class T, class Compare = less<Key>, class Allocator = allocator<pair<const Key, T>>> bool try_get(const map<Key, T, Compare, Allocator>& map, const Key& key, T* value) { const auto it = map.find(key); const bool res = it != end(map); if (res && value != nullptr) { *value = get<1>(*it); } return res; } }
示例场景
场景1:带默认值的配置映射
当你有一个预定义值的映射,但默认值也能适用时,这个方法会很实用:
std::map<TKey, TValue> settings = /* 反序列化得到的配置 */; // ... TValue myValue = /* 默认值 */ ; std::try_get(settings, key, &myValue); // 后续代码直接使用myValue即可, // 它要么是映射中的预定义值,要么是我们设置的默认值
场景2:多缓存回退逻辑
当你有多个已初始化对象的缓存,需要优先匹配对应键的对象,若所有缓存都无匹配则回退到默认实现:
std::map<TKey, TObjKeeper> generalDependecyObjects = /* 初始化通用缓存 */; std::map<TKey, TObjKeeper> specificDependecyObjects = /* 初始化特定缓存 */; TObjKeeper obj; if (!std::try_get(generalDependecyObjects, objectId, &obj) && !std::try_get(specificDependecyObjects, objectId, &obj)) { obj = /* 回退到默认实现 */; }
内容的提问来源于stack exchange,提问作者23W
相关产品推荐
相关产品推荐

