In C++, you created an enumeration that can convert from int to string or from string to int.
#defineENUM(name,...)\
US>class name
public:\
enum Tag {__VA_ARGS__};\
\
private:\
static std::unordered_map<int, std::string>_intToStringMap;\
static std::unordered_map<std::string, int>_stringToIntMap;\
public:\
static std::string toString(inti){\
if(_intToStringMap.empty())
std::string args=#__VA_ARGS__;\
createMap(_intToStringMap,_stringToIntMap, args);\
} \
autoit=_intToStringMap.find(i);\
if(it!=_intToStringMap.end())
return it ->second;\
} else
US>";\
} \
} \
static int to Int(const std::string & str)
if(_stringToIntMap.empty())
std::string args=#__VA_ARGS__;\
createMap(_intToStringMap,_stringToIntMap, args);\
} \
autoit=_stringToIntMap.find(str);\
if(it!=_stringToIntMap.end())
return it ->second;\
} else
return 0;\
} \
} \
};
void createMap(std::unordered_map<int, std::string>&intToStringMap,
std::unordered_map<std::string, int>&stringToIntMap,
const std::string & args)
{
std::string trimmed = ESCUtils::trim(args);
std::vector<std::string>split=ESCUtils::split(trimmed, ", ");
int index = 0;
for(const std::string & s:split)
std::vector<std::string>vect=ESCUtils::split(s, "=");
std::string str =vect.front();
if(vect.size()>=2){
index=ESCUtils::stoi(vect.at(1));
}
intToStringMap.insert(std::make_pair(index,str)));
US>stringToIntMap.insert(std::make_pair(str,index));
index++;
}
}
Trim is a function that returns a blank character, a string without a new line, and split is a function that splits the string with the specified character and returns a vector.
Use Cases
ENUM (RoomIndex,
Room 0 = 0,
Room1,
Room2,
Room 3,
Shower,
ShowerOpen,
Toilet,
ToiletBowl,
ToiletTop,
ToiletSide,
ToiletPaper,
Mirror,
LeftDrawer,
RightDrawer,
TowelRing,
WallPaper,
WallHole,
Corner,
Washing Machine,
Bars,
)
Now that I've used this,
Undefined symbols for architecture arm64:
"RoomIndex::_stringToIntMap", referenced from:
RoomIndex::toString(int) in ESCMainGameLayer.o
"RoomIndex::_intToStringMap", referenced from:
RoomIndex::toString(int) in ESCMainGameLayer.o
ld —symbol(s) not found for architecture arm 64
clang:error:linker command failed with exit code 1 (use-v to see invocation)
A build error was displayed.
How can I fix it?
The static
member variable written in the class
definition is only a "declaration" and there is no "definition."
static std::unordered_map_intToStringMap;\
static std::unordered_map_stringToIntMap;\
These two are not definitions by themselves, so you need to give variable definitions outside of the class definition.
US>Out of Macros class
Definitions
std::unordered_map name::_intToStringMap;\
std::unordered_map name::_stringToIntMap;\
If so, the undefined symbol
beyond "for now" should be resolved.
"First of all" is due to the following problems.
The definition of a static member variable in the header file violates the ODR
.
This ENUM
macro is supposed to be used in the header file, but
Multiple ***.cpp
to use the same ENUM
macro to materialize multiple static member variables, so
Another link error duplicate symbol
will occur.
Hmm...
template
If I fix it to the base, it will become weak symbol and there will be no problem... What do you think?
When multiple identical functions are defined in the template function
I can't afford to think about the implementation now, so I'll leave the implementation to someone else.
Corrected as follows and resolved.
#defineENUM(name,...)\
US>class name
public:\
enum Tag {__VA_ARGS__};\
\
private:\
static std::unordered_map<int, std::string>&getIntToStringMap()
static std::unordered_map<int, std::string>_intToStringMap;\
return_intToStringMap;\
} \
static std::unordered_map<std::string, int>&getStringToIntMap()
static std::unordered_map<std::string, int>_stringToIntMap;\
return_stringToIntMap;\
} \
static void createMap(conststd::string & args)
std::string trimmed = ESCUtils::trim(args);\
std::vector<std::string>split=ESCUtils::split(trimmed,",");\
int index = 0;\
for(const std::string & s:split)
std::vector<std::string>vect=ESCUtils::split(s, "=");\
std::string str =vect.front();\
if(vect.size()>=2){\
index=ESCUtils::stoi(vect.at(1));\
} \
getIntToStringMap().insert(std::make_pair(index,str));\
getStringToIntMap().insert(std::make_pair(str,index));\
index++;\
} \
} \
public:\
static std::string toString(inti){\
if(getIntToStringMap().empty())
std::string args=#__VA_ARGS__;\
createMap(args);\
} \
autoit=getIntToStringMap().find(i);\
if(it!=getIntToStringMap().end())
return it ->second;\
} else
US>";\
} \
} \
static int to Int(const std::string & str)
if(getStringToIntMap().empty())
std::string args=#__VA_ARGS__;\
createMap(args);\
} \
autoit=getStringToIntMap().find(str);\
if(it!=getStringToIntMap().end())
return it ->second;\
} else
return 0;\
} \
} \
};
© 2024 OneMinuteCode. All rights reserved.