Hi, I have a class containing a map member that I want to initialize at declaration time. I know I can do it in the cpp file but I'm having a problem with the order of initialization (static initialization order fiasco).
My questions are:
Is it possible that the scenario in which, the Test's constructor's implementation and the map initialization instruction are in the same cpp file and constructor is called when the map is not initialized yet, could happen?
Is it possible to initialize the map in class like I did?
I get these errors:
in-class initialization of static data member 'std::map<std::basic_string<char>, Test*> Test::a' of incomplete type
temporary of non-literal type 'std::map<std::basic_string<char>, Test*>' in a constant expression
If yes, does this initialization resolve the static initialization order fiasco?
1 2 3 4 5 6 7 8 9 10 11 12
class Test {
public:
static std::map<std::string, Test*> a = {};//this is an error
Test(std::string ID) {
/* in my complete code (where constructor
* implementation and map initialization
* are in a separate .cpp file), this fails, maybe
* because the map is not initialized at the time
* the constructor is being called by a sub class of Test */
a.insert({ID, this});
}
};
Is it possible to initialize the map in class like I did?
Only static constants can be initialized that way.
Is it possible that the scenario in which, the Test's constructor's implementation and the map initialization instruction are in the same cpp file and constructor is called when the map is not initialized yet, could happen?
It requires in-depth Standard reading, but the only way when this scenario potentially could happen if you have global variable Test, which tries to access map in its constructor.
//Binary.hpp
class Binary final : public OperatorCore, public StaticPool<Binary> {
public:
Binary(int ID, std::string name)
: OperatorCore(name), StaticPool<Binary>(ID) {
}
~Binary() {}
};
//Binary.cpp
template<>
const Binary StaticPool<Binary>::pool[] = {
/* this calls OperatorCore's constructor (named Test in the first post)
* where is the insertion in the map instruction */
Binary(0, "a string value")
};
//OperatorCore.hpp
class OperatorCore {
public:
static std::map<std::string, OperatorCore*> symbolMap;
const std::string name;
OperatorCore (std::string name);
virtual ~OperatorCore () {}
};
//OperatorCore.cpp
std::map<std::string, OperatorCore*> OperatorCore::symbolMap{};
OperatorCore::OperatorCore(std::string name) : name(name) {
symbolMap.insert({name, this});//without this line of code, it prints works
}
//StaticPool
template<typename T, typename TKey = int>
class StaticPool {
public:
const TKey ID;
staticconst T pool[];
StaticPool(TKey ID) : ID(ID) {}
virtual ~StaticPool() {}
};
I can't imagine how it can execute the code of the constructor (of class OperatorCore) without having initialized the map if they are in the same translation unit.