效果

```
ENUM_DEFINE ( Color,
Red,
Blue,
) EnumHelper(Color::Red) -> "Red"
EnumHelper(Color::Red, std::toupper) -> "RED"
```

关键技术

  1. __VA_ARGS__

    __VA_ARGS__ 实现了可变参数的宏。

    #define XXX(type, ...) enum class type { __VA_ARGS__ };

    XXX(Color, Red, Blue) 等价于:

    enum class Color
    {
    Red,
    Blue
    };
  2. #__VA_ARGS__

    #__VA_ARGS__ 可将宏的可变参数转为字符串。

    #define XXX(type, ...) #__VA_ARGS__

    XXX(Color, Red, Blue) 等价于:"Red, Blue"

  3. 在函数外执行代码的能力

    在函数体外,可以通过定义全局变量来执行一个函数。需要注意的是,头文件中正常是不能进行变量初始化的,除非加上 static 或者 const

    const int temp = initialize();

    另外,如果多个代码文件 #include 了该头文件,会产生多个变量,即在不同代码文件取得的 temp 变量不是同一个。与之对应,initialize 函数也会调用多次。

  4. 模板函数的静态变量

    函数的静态变量可以用于存放枚举值到枚举字符串的映射,而将枚举类型作为模板参数的模板函数,则可以直接为每种枚举提供了一个映射容器。

  5. 关键代码

    template<typename T>
    string EnumHelper(T key, const std::function<char(char)> processor = nullptr, const char* pszName = NULL)
    {
    static_assert(std::is_enum_v<T>, __FUNCTION__ "'s key need a enum"); static map<T, string> s_mapName; if (nullptr != pszName)
    {
    s_mapName[key] = pszName;
    } std::string res = "";
    auto it = s_mapName.find(key);
    if (it != s_mapName.end())
    {
    res = it->second;
    } if (nullptr != processor)
    {
    std::transform(res.begin(), res.end(), res.begin(), processor);
    } return res;
    } template <class T>
    size_t analystEnum(T enumClass, const char* pszNames)
    {
    static_assert(std::is_enum_v<T>, __FUNCTION__ "'s enumClass need a enum"); cout << "analystEnum: " << pszNames << endl; if (nullptr != pszNames)
    {
    const vector<string>& vecName = split(pszNames, ","); for (int i = 0; i < vecName.size(); ++i)
    {
    if (vecName.at(i).size() > 0)
    {
    EnumHelper((T)(i + 1), nullptr, vecName.at(i).c_str() + (i == 0 ? 0 : 1) );
    }
    } return rand();
    } return rand();
    } #define ENUM_DEFINE(type, ...) enum class type { placeholder, __VA_ARGS__ }; static const size_t g_uEnumSizeOf##type = analystEnum(type::placeholder, #__VA_ARGS__);
  6. 源码地址

c++11 实现枚举值到枚举名的转换的更多相关文章

  1. Kendo Grid控件中将枚举值转为枚举名显示

    我们在开发过程中经常会遇到需要将枚举值转换成名称进行显示的情况.如下我们有这样一个数据源对象: var users = [ {id: 1, name: "similar1", st ...

  2. Day 12:枚举值、枚举类

    jdk1.5新特性之-----枚举 问题:某些方法所接收的数据必须是在固定范围之内的,  解决方案: 这时候我们的解决方案就是自定义一个类,然后是私有化构造函数,在自定义类中创建本类的对象对外使用. ...

  3. C语言基础 (11) 结构体 ,共用体 枚举 typedef

    1 课堂回顾 作用域与生命周期 2 static 局部变量 2 打字游戏 3 内存分区代码分析 4 结构体基本操作 (复合类型[自定义类型 #include <stdio.h> #incl ...

  4. .NET陷阱之六:从枚举值持久化带来大量空间消耗谈起

    好长时间没有写博文了,今天继续. 这次跟大家分享的内容起因于对一个枚举值列表的序列化,下面简化后的代码即能重现.为了明确起见,我显式指定了枚举的基础类型. // 定义一个枚举类型. public en ...

  5. 第三章 EnumUtil根据值获取枚举对象

    项目中使用枚举类的好处这里不再赘述,在使用枚举值时,通常需要根据值来获取枚举对象,下面介绍两种实现方案: 1.在枚举类中定义方法实现 首先给出如下性别枚举类: public enum SexEnum ...

  6. 利用DescriptionAttribute定义枚举值的描述信息 z

    System.ComponentModel命名空间下有个名为DescriptionAttribute的类用于指定属性或事件的说明,我所调用的枚举值描述信息就是DescriptionAttribute类 ...

  7. C# 枚举值 (二) 多属性 操作

    很多时候,我们的枚举值可能需要中英文, 那么可以使用下面的方法: 下面这个类,包含2部分. 1 BaseDescriptionAttribute特性的重载 2 枚举的操作类 EnumOperate n ...

  8. c++之enum(枚举)可以没有枚举名

    转载自https://blog.csdn.net/u013591613/article/details/71215000 C_enum(枚举)可以没有枚举名 如果声明枚举类型时没有指定枚举名,其作用就 ...

  9. Enum 枚举值 (一) 获取描述信息

    封装了方法: public static class EnumOperate { public class BaseDescriptionAttribute : DescriptionAttribut ...

随机推荐

  1. maven项目 子父级工程。

    一 .什么是 maven 子父级工程? 建立一个maven项目,然后在该项目 下创建一个module,子级的maven,他继承于父级项目. 1.新建立 maven项目,file  ------new- ...

  2. C++智能指针使用说明

    导读 STL提供四种智能指针:auto_ptr.unique_ptr.shared_ptr和weak_ptr.其中auto_ptr是C++98提供的解决方案,C++11以后均已摒弃.所有代码在gcc ...

  3. Java流程控制03:顺序结构

    顺序结构 Java的基本结构就是顺序结构,除非特别指明,否则就按照顺序一句一句执行. 顺序结构是最简单的算法结构.从上到下 语句与语句之间,框与框之间是按从上到下的顺序进行的,它是由若干个依次执行的处 ...

  4. freeswitch插件式模块接口实现方式

    概述 freeswitch的外围模块是插件式的,可以动态的加载和卸载,使用起来非常的灵活和方便. 如果我们自己来设计一个开源的代码框架,相信这种插件式的模块结构是非常适合多人合作的模式. 本文对fs的 ...

  5. ExecutorService线程池简单使用

    简介 ExecutorService是Java中对线程池定义的一个接口,它位于java.util.concurrent包中,在这个接口中定义了和后台任务执行相关的方法. 常用方法 public < ...

  6. Thread的打断

    常用方法 public void interrupt() t.interrupt() 打断t线程(设置t线程某给标志位f=true,并不是打断线程的运行),不能打断正在竞争锁的线程. public b ...

  7. sms短信网关对接

    因为工作的需求,需要对接短信网关,业务上就是一个注册用户时,需要发送手机验证码;可能别的公司都是使用第三方接口,但是大点的公司,为了安全,他们都有自己的短信消息中心(SMSC) 1.业务需求 - 1. ...

  8. Mac 使用自带php和Apache 安装配置Xdebug 开启本地调试模式

    Mac 安装配置php xdebug 本地调试 0.原理图 https://paper.seebug.org/308/ 测试demo构建方法 新建空白项目,目录选择Apache默认项目目录 1.下载x ...

  9. 【BZOJ2337】XOR和路径(高斯消元)

    题目链接 大意 给出\(N\)个点,\(M\)条边的一张图,其中每条边都有一个非负整数边权. 一个人从1号点出发,在与该点相连的边中等概率的选择一条游走,直到走到\(N\)号点. 问:将这条路径上的边 ...

  10. zabbix主动上报mysql数据库内容

    zabbix_sender命令支持主动上报数据,web服务端添加对应机器和采集器即可. 2015年刚接触zabbix时候,用的上报sqlserver脚本是select数据后插入到临时表,bcp下载到本 ...