c++ - 如何轻松地将 C++ 枚举映射到字符串

标签 c++ templates enums

我正在使用的一些库头文件中有一堆枚举类型,我希望有一种将枚举值转换为用户字符串的方法 - 反之亦然。

RTTI 不会为我这样做,因为“用户字符串”需要比枚举更具可读性。

蛮力解决方案是一堆这样的函数,但我觉得这有点像 C。

enum MyEnum {VAL1, VAL2,VAL3};

String getStringFromEnum(MyEnum e)
{
  switch e
  {
  case VAL1: return "Value 1";
  case VAL2: return "Value 2";
  case VAL1: return "Value 3";
  default: throw Exception("Bad MyEnum");
  }
}

我有一种直觉,认为有一个使用模板的优雅解决方案,但我还不能完全理解它。

更新:感谢您的建议 - 我应该明确说明枚举是在第三方库 header 中定义的,所以我不想更改它们的定义。

我现在的直觉是避免使用模板并做这样的事情:

char * MyGetValue(int v, char *tmp); // implementation is trivial

#define ENUM_MAP(type, strings) char * getStringValue(const type &T) \
 { \
 return MyGetValue((int)T, strings); \
 }

; enum eee {AA,BB,CC}; - exists in library header file 
; enum fff {DD,GG,HH}; 

ENUM_MAP(eee,"AA|BB|CC")
ENUM_MAP(fff,"DD|GG|HH")

// To use...

    eee e;
    fff f;
    std::cout<< getStringValue(e);
    std::cout<< getStringValue(f);

最佳答案

如果您想将枚举名称本身作为字符串,请参阅 this post . 否则,std::map<MyEnum, char const*>会很好地工作。 (将字符串文字复制到 map 中的 std::strings 没有意义)

对于额外的语法糖,这里是如何编写一个 map_init 类。目标是允许

std::map<MyEnum, const char*> MyMap;
map_init(MyMap)
    (eValue1, "A")
    (eValue2, "B")
    (eValue3, "C")
;

函数template <typename T> map_init(T&)返回 map_init_helper<T> . map_init_helper<T>存储一个 T&,并定义平凡的 map_init_helper& operator()(typename T::key_type const&, typename T::value_type const&) . (从 *this 返回 operator() 允许链接 operator() ,如 operator<< 上的 std::ostream s)

template<typename T> struct map_init_helper
{
    T& data;
    map_init_helper(T& d) : data(d) {}
    map_init_helper& operator() (typename T::key_type const& key, typename T::mapped_type const& value)
    {
        data[key] = value;
        return *this;
    }
};

template<typename T> map_init_helper<T> map_init(T& item)
{
    return map_init_helper<T>(item);
}

由于函数和辅助类是模板化的,您可以将它们用于任何 map 或类似 map 的结构。 IE。它还可以将条目添加到 std::unordered_map

如果您不喜欢编写这些帮助程序,boost::assign 提供了开箱即用的相同功能。

关于c++ - 如何轻松地将 C++ 枚举映射到字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/207976/

相关文章:

java - C++代码在Java中的含义和转换

c++ - 重载函数的不同方式?

c++ - 有什么方法可以知道线程创建成功还是失败?

c++ - 特化模板<typename T, template<typename> class U>

javascript - 在javascript中,如何读取枚举值?

c++ - 另一个类的成员函数中的另一个类的对象

C++ - 未编译的迭代器 vector 的迭代器

c++ - 一种按索引过滤范围,仅从过滤后的索引中获取 min_element 的方法?

swift - 原始类型 'Bool' 不能用任何文字表达

types - 在 Rust 的枚举中使用现有类型