intから文字列、文字列からintに変換できる列挙型
C++で、intから文字列に変換したり、文字列からintに変換できる列挙型を作りました。
#define ENUM(name, ...) \
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(int i){ \
if (_intToStringMap.empty()) { \
std::string args = #__VA_ARGS__; \
createMap(_intToStringMap,_stringToIntMap,args); \
} \
auto it = _intToStringMap.find(i); \
if (it != _intToStringMap.end()) { \
return it->second; \
} else { \
return ""; \
} \
} \
static int toInt(const std::string& str){ \
if (_stringToIntMap.empty()) { \
std::string args = #__VA_ARGS__; \
createMap(_intToStringMap,_stringToIntMap,args); \
} \
auto it = _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));
stringToIntMap.insert(std::make_pair(str, index));
index++;
}
}
trimというのは空白文字、改行を取り除いた文字列を返す関数で、splitは指定した文字で文字列を分割してvectorを返す関数です。
使用例
ENUM(RoomIndex,
Room0=0,
Room1,
Room2,
Room3,
Shower,
ShowerOpen,
Toilet,
ToiletBowl,
ToiletTop,
ToiletSide,
ToiletPaper,
Mirror,
LeftDrawer,
RightDrawer,
TowelRing,
WallPaper,
WallHole,
Corner,
WashingMachine,
Bars,
)
これを使ったところ、
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 arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
と表示されてビルドエラーになりました。
どう直せば良いでしょうか。