简体   繁体   English

静态std :: unordered_map的默认值

[英]Default value of static std::unordered_map

I would like to know the default value of variables inside a struct of static static std::unordered_map<std::string, struct> . 我想知道在静态static std::unordered_map<std::string, struct>的结构中变量的默认值。

Here's my example code: 这是我的示例代码:

#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';
}

The output result: 输出结果:

0
0
Program ended with exit code: 0

Is it safe to think that variables inside Foo are always initialized to 0 in the beginning? 是否可以安全地认为Foo内部的变量始终在开始时初始化为0

Yes, it is actually safe to assume that the values inside Foo are always initialized to zero because of the behaviour of operator[] 是的,实际上可以安全地假设,由于operator[]的行为, Foo中的值总是被初始化为零。

When the default allocator is used, this results in the key being copy/move constructed from key and the mapped value being value-initialized. 使用默认分配器时,这将导致从键复制/移动键,并且对映射的值进行值初始化。

You do not provide a constructor which means that each field in Foo will be value initialized individually which for primitive types means zero initialization. 您没有提供构造函数,这意味着Foo中的每个字段都将分别进行值初始化,对于原始类型而言,这意味着零初始化。

but

The problem you are actually facing here is that a field called "Apple" does not exist in your map. 您实际上在这里面临的问题是地图中不存在名为"Apple"的字段。 Unfortunately the semantics of operator[] are such that if the value does not exist, it will be created on the fly. 不幸的是, operator[]的语义是这样的:如果值不存在,则将在运行中创建它。 You probably didn't even want to access a non-existent field in the map and you are asking whether it is always initialized to zero so that you can use this fact to check whether the element was there. 您甚至可能不想访问地图中不存在的字段,并且正在询问是否始终将其初始化为零,以便可以使用此事实检查元素是否存在。 For this purpose however, you should either use the find() or at() member function. 但是,为此目的,您应该使用find()at()成员函数。

  • find() will return an iterator pointing to the end of the map if the element does not exist. 如果元素不存在,则find()将返回指向地图末尾的迭代器。 That means you could guards the element access using 这意味着您可以使用以下方法保护元素访问

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

    (with the C++17 if statement initializer) (使用C ++ 17 if语句初始化程序)

  • at() will throw an exception if the element is not found. 如果找不到元素,则at()将引发异常。

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

    This will crash your program with a std::out_of_range exception. 这将使您的程序崩溃,并带有std::out_of_range异常。 You might feel temped to catch this exception to check whether the element existed. 您可能会想捕获此异常以检查元素是否存在。 Don't do this. 不要这样 It is very bad practice to use exceptions for control flow. 将异常用于控制流是非常不好的做法。 On top of that exception are dead slow when they are being thrown. 最重要的是,在抛出异常时,它们的速度非常慢。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM