如何对嵌套地图使用 map::find() 方法?

How to use the map::find() method for a nested map?

我有一个map<int, map<int,int>> mymap;

如何对这样的嵌套 map 使用 find() 方法?

如果我有 map<int,int> mymap, mymap.find(key) 它会给出一个结果。但是超过 1 个键的嵌套 maps 呢?

mymap.find() 将搜索第一个键和 return 指向包含该键关联值的 std::pair 的迭代器,即 std::map.

然后 find() std::map 将搜索第二个键,return 将迭代器指向包含其关联值的 std::pair,这是一个 int.

例如:

map<int, map<int,int>> mymap;
auto it1 = mymap.find(key1);
if (it1 != mymap.end()) {
    auto it2 = it1->second.find(key2);
    if (it2 != it1->second.end()) {
        // use it2->second as needed...
    }
}

之后

auto entry = mymap.find(key);

您发现 entrystd::pair 的迭代器,其中包含 (const!) 键和值,后者在您的例子中是另一个映射,因此:

auto subEntry = entry->second.find(subKey)

(前提当然是entry != mymap.end()!)

还要注意还有std::map::at.

如果匹配的键不存在,它会抛出 std::out_of_range,但您的情况的用法很简单。

auto value = mymap.at(key1).at(key2);

如果您不确定密钥是否存在,您可以捕获此异常或使用 中的方法。

最好提供一种工具来处理此类情况。

所以应该采用辅助函数或通用模板的形式:

template<typename T, typename Key>
auto optional_at(T& x, Key&& key)
    -> std::optional<typename T::mapped_type>
{
    auto it = x.find(std::forward<Key>(key));
    if (it == x.end()) 
        return {};
    return it->second;
}

template<typename T, typename Key, typename ...Keys>
auto optional_at(T& x, Key&& key, Keys&&...keys)
    -> decltype(optional_at(x[key], std::forward<Keys>(keys)...))
{
    auto it = x.find(std::forward<Key>(key));
    if (it != x.end()) 
        return optional_at(it->second, std::forward<Keys>(keys)...);
    return {};
}

//---------------------
int main()
{
    std::map<int, std::map<int, std::string>> m{
        {1, {{1, "one-one"}}},
        {2, {{1, "two-one"}, {2, "two-two"}}}
    };
    
    ...
    print(std::cout, optional_at(m, 1, 2)) << '\n';
    print(std::cout, optional_at(m, 2, 1)) << '\n';
    print(std::cout, optional_at(m, 2, 2)) << '\n';
    ...

    return 0;
}

Live demo

那么使用这个的时候意图就很简单了。