c++11 实现枚举值到枚举名的转换问题

目录
  • 效果
  • 关键技术
    • __VA_ARGS__
    • #__VA_ARGS__
    • 在函数外执行代码的能力
    • 模板函数的静态变量
    • 关键代码
    • 源码地址

效果

ENUM_DEFINE ( Color,
    Red,
    Blue,
)

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

关键技术

__VA_ARGS__

__VA_ARGS__ 实现了可变参数的宏。

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

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

enum class Color
{
    Red,
    Blue
};

#__VA_ARGS__

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

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

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

在函数外执行代码的能力

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

const int temp = initialize();

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

模板函数的静态变量

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

关键代码

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

源码地址

到此这篇关于c++11 实现枚举值到枚举名的转换的文章就介绍到这了,更多相关c++11 枚举值到枚举名的转换内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C++11 强类型枚举相关总结

    枚举就是定义一个类别,并且穷举统一类别下的个体以供代码使用. C++98 枚举存在的缺陷: 无论是具名枚举的名字还是枚举类型中的成员,都是全局范围的,其作用域是全局的. 如果在不同的枚举中定义了相同的枚举成员,则会出现重复声明(redeclaration)错误. enum PUBLIC_COLOR { RED, YELLOW, GREEN }; enum PRIVATE_COLOR { RED, BLACK, PURPLE }; // RED 重定义 enum PUBLIC_COLOR { WH

  • 详解C++11强类型枚举

    1.传统枚举类型的缺陷 枚举类型是C/C++中用户自定义的构造类型,它是由用户定义的若干枚举常量的集合.枚举值对应整型数值,默认从0开始.比如定义一个描述性别的枚举类型. enum Gender{Male,Female}; 其中枚举值Male被编译器默认赋值为0,Female赋值为1.传统枚举类型在设计上会存在以下几个问题. (1)同作用域同名枚举值会报重定义错误.传统C++中枚举常量被暴漏在同一层作用域中,如果同一作用域下有两个不同的枚举类型,但含有同名的枚举常量也是会报编译错误的,比如: e

  • C和C++11之enum枚举的具体使用方法

    一.前言 由于C++项目中用了相对比较多的枚举(enum),正常情况下,枚举变量都是占用一个整形类型的大小,但是项目中枚举(enum)只需要使用到一个字节的大小,因为是在嵌入式设备上执行的代码,资源比较少,那么如果枚举都是按照int型大小来使用的话,这无疑是一种资源浪费. 所以就想有没有一种办法可以控制枚举(enum)占用内存的办法.所幸,通过查找资料,发现C++11的新特性刚好加入了控制枚举大小的机制.那么接下来我们就来看看,枚举(enum)在C++11标准有哪些变化?以及C和C++11中的枚

  • 关于C++11中限定作用域的枚举类型的问题

    枚举类型是将一组有限的整数常量组织在一起用以描述变量可取值范围的一种数据类型.C++中有两种类型的枚举:不限定作用域的枚举类型和限定作用域的枚举类型.限定作用域的枚举类型是C++11标准引入的新类型. ● 限定作用域枚举类型是为了弥补不限定作用域枚举类型的不足而出现的,不限定作用域的枚举类型不是类型安全的,主要表现在如下几个方面: ● 不限定作用域的枚举类型中的枚举成员被视为整数,两种不同的枚举类型之间可以进行比较.两种不同类型的数据进行比较,可能带来数据类型转换,引起数据表示不完整. ● 不限

  • 结合C++11的新特性来解析C++中的枚举与联合

    枚举 枚举是用户定义的类型,其中包含一组称为枚举器的命名的整型常数. 语法 // unscoped enum: enum [identifier] [: type] {enum-list}; // scoped enum: enum [class|struct] [identifier] [: type] {enum-list}; // Forward declaration of enumerations (C++11): enum A : int; // non-scoped enum mu

  • c++11 实现枚举值到枚举名的转换问题

    目录 效果 关键技术 __VA_ARGS__ #__VA_ARGS__ 在函数外执行代码的能力 模板函数的静态变量 关键代码 源码地址 效果 ENUM_DEFINE ( Color, Red, Blue, ) EnumHelper(Color::Red) -> "Red" EnumHelper(Color::Red, std::toupper) -> "RED" 关键技术 __VA_ARGS__ __VA_ARGS__ 实现了可变参数的宏. #defin

  • Spring MVC Controller传递枚举值的实例

    目录 Spring MVC Controller传递枚举值 功能描述 枚举定义 定义Controller类 请求示例 结论 Spring MVC 枚举传值问题 最后找到解决方案 Spring MVC Controller传递枚举值 功能描述 本文将通过一个小示例,展示在请求参数中传递枚举值. 枚举定义 角色类定义: public enum RoleEnum { EMPLOYEE((short)1, "Employee"), MANAGER((short)2, "Manager

  • C# 从枚举值获取对应的文本描述详解

    C# 从枚举值获取对应的文本描述详解 有时枚举值在显示时,需要显示枚举值对应的文本串.一种方案是在调用的地方使用switch或者if来判断枚举值,然后赋给不同的文本串,但这样一来,如果有较多的地方都用到的时候就会比较麻烦.当然有人说,这种情况下,可以针对这种枚举值封装一个方法,然后来调用.那如果有多个枚举类型都有这样的需求呢?有没有什么比较通用的解决办法?有的. 这里需要用到Description属性,给每个枚举值都赋上一个该属性,然后在该属性中赋上要描述的文本串.比如 #region YesN

  • c#枚举值增加特性说明(推荐)

    通过特性给一个枚举类型每个值增加一个字符串说明,用于打印或显示. 自定义打印特性 [AttributeUsage(AttributeTargets.Field)] public class EnumDisplayAttribute : Attribute { public EnumDisplayAttribute(string displayStr) { Display = displayStr; } public string Display { get; private set; } } 打

  • springboot validator枚举值校验功能实现

    这篇文章主要介绍了springboot validator枚举值校验功能实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一.前言 在spring项目中,校验参数功能使用hibernate validator是一个不错的选择,我们的项目中也是使用它来进行校验的,省去了很多难看的校验逻辑,使代码的可读性也大大增加,本章将带你使用hibernate validator自定义注解功能实现一个 枚举值校验的逻辑. 二.需求 我们先明确下我们的需求,在

  • python3中确保枚举值代码分析

    有的小伙伴对于枚举的理解很模糊,其实我们可以把它看成一个数量的大管家,对其中的每一个数进行检查,保证里面的数字都没有重复的,这就是枚举的用法.相信听完小编的解释,小伙伴们已经可以结合理解了枚举的定义.今天我们主要教大家用代码来在python3中确保枚举值,具体的操作方法我们继续往下看. 创建 枚举语法与 class 语法相同,枚举的定义可以通过继承 Enum 的方式来实现, 看一下示例: from enum import Enum class WeekDay(Enum): Mon = 0 Tue

  • C/C++ int数与多枚举值互转的实现

    在C/C++在C/C++的开发中经常会遇到各种数据类型互转的情况,正常的互转有:单个枚举转int数,int数转float数,float数转double数等.但是我们有时也会遇到多个枚举值与数字互转的情形(例如多个算法类型枚举开启标志转成数字,这个数字来表示多个标志位,按位来表示).这样一个数字就能表示很多个标志位了,针对内存较少的嵌入式设备,这么操作可以达到节约内存消耗,提高程序运行效率的目的. Demo示例 demo核心知识点:通过位运算符(布尔位运算符:"~"."&

  • Mybatis条件if test如何使用枚举值

    目录 Mybatis条件if test使用枚举值 1.正确 2.错误 Mybatis里使用枚举Enum判断 TestTypeEnum定义如下 Mybatis条件if test使用枚举值 1.正确 package com.weather.weatherexpert.common.utils; /** * <p>Title: </p> * <p>Description: </p> * * @Author * @CreateTime */ public enum

  • vue对枚举值转换方式

    目录 vue对枚举值转换 vue中"枚举"的用法 下面介绍一种(基于vue+element+admin) vue对枚举值转换 最近再做项目中碰到了这样一个问题,前端vue对后端返回数据中的枚举值做处理.之前枚举值的转换都在后端返回dto中做处理,首次碰到这种问题,先将解决方案抛出,希望能帮到有缘人: <el-table v-loading="loading.table" :data="data.list.items" fit stripe

随机推荐