c++ - std::map 中不存在的项上的运算符[]的返回值

标签 c++ return-value stdmap

在基于 std::map 构建容器时,我遇到了意外行为:检索不存在键的值不会提供使用默认构造函数构造的新对象。

我在这里缺少什么?

简化的测试用例程序:

#include <cstdio>
#include <algorithm>
#include <map>
#include <string>


static std::string to_lower(const std::string& str)
{
    std::string lower_label;
    std::transform(str.begin(), str.end(), lower_label.begin(), ::tolower);
    return lower_label;
}

class Int {
   public:
      Int () : i(0) { }
      Int (int _i) : i(_i) { }

      int val() const { return i; }

   private:
      int i;
};

std::map<std::string, Int> ints;

Int GetInt(const std::string& label)
{
    std::string lower_label = to_lower(label);
    return ints[lower_label];
}

void AddInt(Int image, const std::string& label)
{
    std::string lower_label = to_lower(label);
    ints[lower_label] = image;
}

int main()
{
    Int k;
    printf ("default Int: %d\n", k.val());

    AddInt(Int(5), "I5");
    Int i = GetInt("i5");
    printf ("existing Int: %d\n", i.val());

    Int j = GetInt("LaLa");
    printf ("non-existing Int:  %d\n", j.val());  // expecting 0

    return 0;
}

输出:

default Int: 0
existing Int: 5
non-existing Int:  5

最佳答案

您的转换写入空字符串,因此程序具有未定义的行为。

实际情况是,当您返回时,lower_label 的长度仍然为零,因此每次调用 to_lower 时,您都会得到相同的键:一个空字符串。这意味着您的 map 有一个条目,并且每次调用 GetInt 都会返回相同的条目。

但是由于您有未定义的行为,所以您很幸运它不会崩溃或删除您的磁盘。

在尝试写入之前,您需要使用 back_insert_iterator 或正确设置字符串大小。

或者:

  std::string lower_label;
  std::transform(str.begin(), str.end(), std::back_inserter(lower_label), ::tolower);

或者:

  std::string lower_label;
  lower_label.resize(str.size());
  std::transform(str.begin(), str.end(), lower_label.begin(), ::tolower);

关于c++ - std::map 中不存在的项上的运算符[]的返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26120046/

相关文章:

scala - scala闭包/匿名函数中的多个返回点

c++ - 我想在 C++ 中为 map<> 的给定 KEY 返回一个 VALUE。如果 KEY 不在 map<> 中,返回什么?

Reactjs 函数不返回 JSX

c++ - 如何从 std::map 中检索所有键(或值)并将它们放入 vector 中?

c++ - 如何使用用户定义的键控制和修改 std::map 排序

c++ - 强制 Qt5 从 exe 目录加载 SSL dll

c++ - boost::序列化段错误

c++ - 带有提示的 std::map::insert_or_assign 的复杂性

c++ - 发布版本中的错误的常见原因在 Debug模式下不存在

c++ - '&'在 "std::vector<byte>& stream;"中代表什么