Zac*_*Lee 9 c++ static dictionary initialization
我想知道 static 结构中变量的默认值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';
}
Run Code Online (Sandbox Code Playgroud)
输出结果:
0
0
Program ended with exit code: 0
Run Code Online (Sandbox Code Playgroud)
认为内部Foo的变量总是0在开始时被初始化是否安全?
Hen*_*nke 17
是的,假设内部的值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';
}
Run Code Online (Sandbox Code Playgroud)
(使用 C++17if语句初始值设定项)
at() 如果未找到元素,将抛出异常。
std::cout << map.at("Apple").num << '\n';
std::cout << map.at("Apple").state << '\n';
Run Code Online (Sandbox Code Playgroud)
这将使您的程序崩溃并出现std::out_of_range异常。您可能想捕获此异常以检查元素是否存在。不要这样做。将异常用于控制流是非常糟糕的做法。最重要的是,抛出异常时异常缓慢。