静态std::unordereded_map的默认值

Default value of static std::unordered_map

本文关键字:默认值 map unordereded std 静态      更新时间:2023-10-16

我想知道静态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是否安全?

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

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

您没有提供构造函数,这意味着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++17if语句初始值设定项(

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

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

    这将使您的程序崩溃,并出现std::out_of_range异常。您可能会觉得有必要捕捉这个异常来检查元素是否存在。不要这样做。对控制流使用异常是非常糟糕的做法。除此之外,在抛出异常时速度非常慢。