为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C++
12345678_0001 2019-10-15 14:36:59
我在使用的某些库头文件中有一堆枚举类型,并且我希望有一种将枚举值转换为用户字符串的方法,反之亦然。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");  }}我有一种直觉,认为使用模板是一种优雅的解决方案,但是我还不能完全理解。更新:感谢您的建议-我应该明确指出枚举是在第三方库标头中定义的,因此我不想更改它们的定义。我现在的直觉是避免模板并执行以下操作: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);
查看完整描述

3 回答

?
慕仙森

TA贡献1827条经验 获得超7个赞

如果您希望枚举将自己命名为字符串,请参见这篇文章。否则,a std::map<MyEnum, char const*>会很好地工作。(将字符串文字复制到映射中的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::ostreamS)


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);

}

由于函数和帮助程序类是模板化的,因此可以将它们用于任何地图或类似地图的结构。即它也可以添加条目到std::unordered_map


如果您不喜欢编写这些帮助器,则boost :: assign提供了相同的功能。


查看完整回答
反对 回复 2019-10-15
?
侃侃无极

TA贡献2051条经验 获得超10个赞

自动从另一表格中生成一种表格。


资源:


enum {

  VALUE1, /* value 1 */

  VALUE2, /* value 2 */

};

产生:


const char* enum2str[] = {

  "value 1", /* VALUE1 */

  "value 2", /* VALUE2 */

};

如果枚举值很大,则生成的表单可以使用unordered_map <>或康斯坦丁建议的模板。


资源:


enum State{

  state0 = 0, /* state 0 */

  state1 = 1, /* state 1 */

  state2 = 2, /* state 2 */

  state3 = 4, /* state 3 */


  state16 = 0x10000, /* state 16 */

};

产生:


template <State n> struct enum2str { static const char * const value; };

template <State n> const char * const enum2str<n>::value = "error";


template <> struct enum2str<state0> { static const char * const value; };

const char * const enum2str<state0>::value = "state 0";

例:


#include <iostream>


int main()

{

  std::cout << enum2str<state16>::value << std::endl;

  return 0;

}


查看完整回答
反对 回复 2019-10-15
  • 3 回答
  • 0 关注
  • 865 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信