我想知道静态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
吗?
答案 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
异常。您可能会想捕获此异常以检查元素是否存在。不要这样将异常用于控制流是非常不好的做法。最重要的是,它们被抛出时非常缓慢。