unordered_map:如果键不在映射中,要返回什么

unordered_map: what to return if key is not in map?

本文关键字:映射 什么 返回 map 如果 unordered      更新时间:2023-10-16

作为这个问题的序言,我不得不说我是一名Java程序员,因此比C++更习惯于Java中地图的语义。 在Java中,在Map中查找键时,通常会返回null。我正在将我们的一些代码转换为 c++,并试图在与unordered_map交互时找到 c++ 的做事方式。

具体来说,我有一个包含unordered_map的类。我没有将映射直接公开给客户端代码,而是有 2 个包装函数,一个用于将键/值对放入映射中,另一个用于检索指定键的值,即:

void set_tag_value(string tag, string value);
string& get_tag_value(string tag);

如果我使用 unordered_map.at() 来检索值,那么它将抛出我的代码需要捕获的异常,或者允许它传播到客户端代码。 (不过,传播例外对我来说似乎不友好(。

也许另一种方法是将返回值更改为string*类型,如果未找到,则返回 NULL(这是 Java 的方式(,但随后用户需要检查 NULL(这也不太友好(。

所以我的问题分为两部分:

  1. 处理失败查找的开发人员友好方法是什么,什么返回值是有用的(异常、NULL、空字符串或其他内容(?

  2. 在我的代码中,当您期望它可能无法找到键、at(( 和 catch 异常或查找并检查迭代器 == map.end(( 时,使用哪种地图查找方法更典型?(这部分问题是我只是想学习 c++ 的做事方式(。

感谢您的任何建议!

在我看来,最好不要返回指向您保持私密的地图内容的指针,因为如果地图更改,指针可能会失效。

我会让函数返回一个成功代码 ( bool ( 并传递对字符串的引用以实际返回值(如果找到(。例如

bool get_tag_value(const string& tag, string& value)
{
    auto t = my_map.find(tag);
    if (t == my_map.end()) return false;
    value = t->second;
    return true;
}

请注意,如果找不到键,unordered_map::at()将抛出,unordered_map::find()返回无效的迭代器 ( unordered_map::end() ( - 因此您可以避免以这种方式处理异常。

如果你想坚持返回一个字符串,那么如果找不到键,只需返回一个空字符串(return string();(。

以下是我会考虑的 2 个选项,具体取决于您使用 boost 的意愿:

返回指针:

/* const? */ string* get_tag_value_ptr(const string& tag)
{
    auto it = theMap.find(tag);
    if (it != theMap.end()) {
        return &it->second;
    }
    return nullptr;
}

返回可选引用:

boost::optional</* const? */ string&> get_tag_value_opt(const string& tag)
{
    auto it = theMap.find(tag);
    if (it != theMap.end()) {
        return it->second;
    }
    return boost::none;
}

希望我们很快就会有std::optional,尽管它已从 C++14 推迟。

这些检索方法不需要从映射中复制值。通过 out 参数返回意味着复制该值。我想这取决于你的要求是什么。