初始化地图被报告为空的奇怪行为
Strange behaviour where initialised map being reported as empty
我有以下三个文件:
test.h
#pragma once
#include <iostream>
class Test{
public:
Test(std::string string);
};
test.cpp
#include "test.h"
#include <map>
std::map<int, int> HEY = {
{1, 45},
{2, 2}
};
Test::Test(std::string string) {
std::cout << "hello" << std::endl;
if (HEY.empty()) {
std::cout << "Is empty!" << std::endl;
} else {
std::cout << "Not empty!" << std::endl;
}
}
Source.cpp
#include "test.h"
Test test("hey");
int main() {
return 0;
}
预期输出
hello
Not empty!
实际输出
hello
Is empty!
当我 运行 Microsoft Visual Studio 2019 中的程序时,我期望“不为空!”被输出,表明映射 HEY
中有元素,因为它是用两对初始化的。但是输出实际上是“是空的!”。
我不想在 main 函数中初始化 test
,因为我希望它是一个全局变量,尽管我注意到当我在 main 函数中创建它时我得到了正确的输出。
我做错了什么?这是 compiler/linker 错误吗?我没有适当地声明 HEY
地图吗?重要的是 test
仍然是一个全局变量。
您的 HEY
和 test
对象都在程序启动时在调用 main()
之前在全局内存中创建。 test
对象只是首先被创建,这就是为什么当 test
的构造函数是 运行 时 map
仍然是空的(从技术上讲,map
'甚至尚未创建)。参见 Static Initialization Order Fiasco。
将 test
对象的创建移动到 main()
中,您应该会看到您期望的输出。否则,您将不得不将 HEY
的初始化延迟到 test
之后,例如将 HEY
包装在一个单例中,该单例在第一次使用时对其进行初始化,例如:
#include "test.h"
#include <map>
struct MapSingleton {
static std::map<int, int>& Get() {
static std::map<int, int> HEY = {
{1, 45},
{2, 2}
};
return HEY;
}
};
Test::Test(std::string string) {
std::cout << "hello" << std::endl;
if (MapSingleton::Get().empty()) {
std::cout << "Is empty!" << std::endl;
} else {
std::cout << "Not empty!" << std::endl;
}
}
我有以下三个文件:
test.h
#pragma once
#include <iostream>
class Test{
public:
Test(std::string string);
};
test.cpp
#include "test.h"
#include <map>
std::map<int, int> HEY = {
{1, 45},
{2, 2}
};
Test::Test(std::string string) {
std::cout << "hello" << std::endl;
if (HEY.empty()) {
std::cout << "Is empty!" << std::endl;
} else {
std::cout << "Not empty!" << std::endl;
}
}
Source.cpp
#include "test.h"
Test test("hey");
int main() {
return 0;
}
预期输出
hello
Not empty!
实际输出
hello
Is empty!
当我 运行 Microsoft Visual Studio 2019 中的程序时,我期望“不为空!”被输出,表明映射 HEY
中有元素,因为它是用两对初始化的。但是输出实际上是“是空的!”。
我不想在 main 函数中初始化 test
,因为我希望它是一个全局变量,尽管我注意到当我在 main 函数中创建它时我得到了正确的输出。
我做错了什么?这是 compiler/linker 错误吗?我没有适当地声明 HEY
地图吗?重要的是 test
仍然是一个全局变量。
您的 HEY
和 test
对象都在程序启动时在调用 main()
之前在全局内存中创建。 test
对象只是首先被创建,这就是为什么当 test
的构造函数是 运行 时 map
仍然是空的(从技术上讲,map
'甚至尚未创建)。参见 Static Initialization Order Fiasco。
将 test
对象的创建移动到 main()
中,您应该会看到您期望的输出。否则,您将不得不将 HEY
的初始化延迟到 test
之后,例如将 HEY
包装在一个单例中,该单例在第一次使用时对其进行初始化,例如:
#include "test.h"
#include <map>
struct MapSingleton {
static std::map<int, int>& Get() {
static std::map<int, int> HEY = {
{1, 45},
{2, 2}
};
return HEY;
}
};
Test::Test(std::string string) {
std::cout << "hello" << std::endl;
if (MapSingleton::Get().empty()) {
std::cout << "Is empty!" << std::endl;
} else {
std::cout << "Not empty!" << std::endl;
}
}