有一个静态模板类,用于枚举到字符串的转换,反之亦然。
下面的代码在 enum.cpp 模块中生成一组不可读的模板相关编译错误:
//helpers.hpp
namespace helpers {
template<typename T>
class Convert {
public:
static std::string toStr(T) { return m_convert[T]; }
static T fromStr(std::string) { return m_convert.begin()->first; }
private:
static std::map<T, std::string> m_convert;
};
}
...
//enum.hpp
namespace A::B::C::D {
enum class ImportantEnum {
item1,
item2,
};
}
...
//enum.cpp
#include "helpers.hpp"
#include "enum.hpp"
namespace A::B::C::D {
template<>
std::map<ImportantEnum, std::string> helpers::Convert<ImportantEnum>::m_convert = {
{item1, "item1"},
{item2, "item2"},
}
}
...
//enum_lover.cpp
#include "helpers.hpp"
#include "enum.hpp"
namespace A::B::C::D {
void do() {
std::string s = helpers::Convert<ImportantEnum>::toStr();
}
}
如果我在 enum.cpp 中使用以下代码,它就会开始编译并工作:
//enum.cpp
#include "helpers.hpp"
#include "enum.hpp"
namespace A::B::C::D {
template<>
std::map<A::B::C::D::ImportantEnum, std::string> helpers::Convert<A::B::C::D::ImportantEnum>::m_convert = {
{A::B::C::D::item1, "item1"},
{A::B::C::D::item2, "item2"},
}
}
有没有办法更方便的实现这种helper?
这应该就是您正在寻找的。
我没有看到需要类模板。在下面的代码中,
Convert
是一个常规类。如果需要的话,应该可以用它制作一个模板。
在实践中,我会考虑合并枚举和辅助文件。我在这里将它们分开,以便符合您原来的问题。
// enum.hpp
#ifndef ENUM_H
#define ENUM_H
namespace A::B::C::D {
enum class ImportantEnum {
item1 = 42,
item2,
};
}
#endif
// end file: enum.hpp
// helpers.hpp
#ifndef HELPERS_H
#define HELPERS_H
#include <map>
#include <string>
#include "enum.hpp"
namespace A::B::C::D
{
class Convert {
public:
static std::string toStr(ImportantEnum const e);
static ImportantEnum fromStr(std::string const& s);
private:
static std::map<ImportantEnum, std::string> m_enum_lookup;
static std::map<std::string, ImportantEnum> m_string_lookup;
};
}
#endif
// end file: helpers.hpp
// helpers.cpp
#include <map>
#include <string>
#include "enum.hpp"
#include "helpers.hpp"
namespace A::B::C::D
{
std::string Convert::toStr(ImportantEnum const e) {
return m_enum_lookup[e];
}
ImportantEnum Convert::fromStr(std::string const& s) {
return m_string_lookup[s];
}
std::map<ImportantEnum, std::string> Convert::m_enum_lookup {
{ ImportantEnum::item1, "item1" },
{ ImportantEnum::item2, "item2" }
};
std::map<std::string, ImportantEnum> Convert::m_string_lookup {
{ "item1", ImportantEnum::item1 },
{ "item2", ImportantEnum::item2 }
};
}
// end file: helpers.cpp
// main.cpp
#include <iostream>
#include "enum.hpp"
#include "helpers.hpp"
int main() {
using A::B::C::D::ImportantEnum;
using A::B::C::D::Convert;
auto s1{ Convert::toStr(ImportantEnum::item1) };
auto s2{ Convert::toStr(ImportantEnum::item2) };
auto from1{ Convert::fromStr(s1) };
auto from2{ Convert::fromStr(s2) };
auto const to1{ Convert::toStr(from1) };
auto const to2{ Convert::toStr(from2) };
std::cout
<< "Convert::toStr(ImportantEnum::item1) : \"" << to1 << '"'
<< "\nConvert::toStr(ImportantEnum::item2) : \"" << to2 << '"'
<< "\n\n";
return 0;
}
// end file: main.cpp
Convert::toStr(ImportantEnum::item1) : "item1"
Convert::toStr(ImportantEnum::item2) : "item2"