静态std :: unordered_map的默认值

时间:2018-08-03 07:44:38

标签: c++ dictionary static initialization

我想知道静态static std::unordered_map<std::string, struct>结构中变量的默认值。

这是我的示例代码:

#include <iostream>
#include <string>
#include <unordered_map>

int main()
{
    enum MyStateType
    {
        MY_STATE_NEW,
        MY_STATE_RUN,
        MY_STATE_FREE
    };
    struct Foo
    {
        int num;
        MyStateType state;
    };
    static std::unordered_map<std::string, Foo> map;

    std::cout << map["Apple"].num << '\n';
    std::cout << map["Apple"].state << '\n';
}

输出结果:

0
0
Program ended with exit code: 0

可以安全地认为Foo内的变量总是从一开始就初始化为0吗?

1 个答案:

答案 0 :(得分:3)

是的,实际上可以假设Foo内的值由于operator[]的行为总是被初始化为零。

  

使用默认分配器时,这将导致从键复制/移动键,并且对映射值进行值初始化。

您没有提供构造函数,这意味着Foo中的每个字段都将分别进行值初始化,对于原始类型而言,这意味着初始化为零。

但是

您实际上要面对的问题是,地图中不存在名为"Apple"的字段。不幸的是operator[]的语义使得如果该值不存在,它将被动态创建。您甚至可能不想访问地图中不存在的字段,并且正在询问是否始终将其初始化为零,以便可以使用此事实检查元素是否存在。但是,为此,您应该使用find()at()成员函数。

  • find()将返回一个迭代器,该迭代器指向地图的末尾(如果元素不存在)。这意味着您可以使用

    来保护元素访问
    if (auto apple = map.find("Apple"); apple != map.end()) {
        std::cout << apple->second.num << '\n';
        std::cout << apple->second.state << '\n';
    }
    

    (使用C ++ 17 if语句初始化程序)

  • 如果找不到该元素,
  • at()将引发异常。

    std::cout << map.at("Apple").num << '\n';
    std::cout << map.at("Apple").state << '\n';
    

    这将使您的程序崩溃,并出现std::out_of_range异常。您可能会想捕获此异常以检查元素是否存在。不要这样将异常用于控制流是非常不好的做法。最重要的是,它们被抛出时非常缓慢。