validinteger是某个enum类项(c++ 11)
validate integer is some enum class item (C++11)
我有一些enum类
enum class Foo { A=1, B=18 , Z=42 };
我想检查是否可以将某个整数转换为Foo
。理想的做法是什么?这是用于运行时检查(在编译时还不知道整数)
显然,我可以用困难的方式做到这一点(写一个函数bool CheckEnum(Foo);
,在所有情况下都返回true,除了默认情况),但我希望有一个更优雅的机制来避免这么多的编写。MPL或Boost.Preprocessor
将是一个完全可以接受的解决方案,但遗憾的是,我对其中一个知之甚少
这个问题的解决方案是放弃枚举,并将其替换为使用XMACROs创建的一些数组。
没有"理想"的方法。所有的方法都必须涉及一些手工工作。
您需要创建包含所有可接受值的数据结构。然后用所需的运行时值搜索该数据结构。std::set
或std::unordered_set
可以满足此目的。
您的主要困难将是维护该列表,因为每次更改enum class
时它都需要更新。
好吧,我有点受够了这个问题(我的一些枚举有将近100个条目)所以我决定用代码生成来解决这个问题,这可能不是每个人都喜欢的,但我意识到这真的没什么大不了的。
基本上我选择了Python Cog,它允许我在我的。h和。cpp文件的注释中嵌入Python片段,并自动生成代码。我把它当作一个非常智能的命令式宏系统来使用:
我在Test.h
/*[[[cog
#----------- definitions
import cog
def createCategoryConstants( enumVar , bitShift ):
categoryIndex = 0
for cat in enumVar:
cog.outl(' const unsigned int %s_op_mask = (%d << %d); ' %(cat[0] , categoryIndex , bitShift))
categoryIndex += 1
cog.outl('nn')
def createMultiCategoryEnum( enumVar , enumTypename ):
cog.outl(' enum class %s { ' % enumTypename )
categoryIndex = 0
for i in enumVar:
itemIndex = 0
catName = 'NotExpected'
remainingCategories = len(enumVar)- categoryIndex - 1
for j in i:
if (itemIndex == 0):
catName = j
itemIndex = 1
continue
enumItemIndex = 0
for enumItem in j:
remainingEnums = len(j) - enumItemIndex - 1
currentLine = ' %s = %s_op_mask | %d ' %(enumItem, catName, enumItemIndex)
if (remainingCategories != 0 or remainingEnums != 0):
currentLine += ' , '
cog.outl(currentLine)
enumItemIndex += 1
itemIndex += 1
cog.outl('') #empty line to separate categories
categoryIndex += 1
cog.outl(' };nn')
def createIndexFromEnumFunction( enumVar , enumTypename , functionName ):
cog.outl('uint32_t %s(%s a) { n switch (a)n {' % (functionName , enumTypename) )
absoluteIndex = 0
for cat in enumVar:
elemInCat = 0
for i in cat:
if elemInCat != 0:
for enumItem in i:
cog.outl('case %s:' % enumItem)
cog.outl(' return %d; n' % absoluteIndex)
absoluteIndex += 1
elemInCat += 1
cog.outl(' } n } nn ')
def createMultiEnum( enumVar , enumTypename ):
createCategoryConstants( enumVar , 4)
createMultiCategoryEnum( enumVar , enumTypename )
createIndexFromEnumFunction( enumVar , enumTypename , 'FromOpToIndex' )
#------------- generation
multiEnum =[ ['CatA', ['A1', 'A2' , 'A3_foo']] , ['CatSuper8' , ['Z1_bla' , 'Z10' , 'Z11']] ]
createMultiEnum( multiEnum , 'multiFooEnum')
]]]*/
//[[[end]]]
然后我在Makefile预构建步骤中添加了cog调用:
.build-pre:
# Add your pre 'build' code here...
python /usr/local/bin/cog.py -I../../../tools/cog/ -r *.h
结果显示在下面:
]]]*/
const unsigned int CatA_op_mask = (0 << 4);
const unsigned int CatSuper8_op_mask = (1 << 4);
enum class multiFooEnum {
A1 = CatA_op_mask | 0 ,
A2 = CatA_op_mask | 1 ,
A3_foo = CatA_op_mask | 2 ,
Z1_bla = CatSuper8_op_mask | 0 ,
Z10 = CatSuper8_op_mask | 1 ,
Z11 = CatSuper8_op_mask | 2
};
uint32_t FromOpToIndex(multiFooEnum a) {
switch (a)
{
case A1:
return 0;
case A2:
return 1;
case A3_foo:
return 2;
case Z1_bla:
return 3;
case Z10:
return 4;
case Z11:
return 5;
}
}
//[[[end]]]
所以,现在我的枚举验证是关于确保代码生成(在编译时调用)是正确完成的
相关文章:
- 类初始值设定项检查某些输入
- 当初始值设定项是基类名时'initializer does not name a non-static data member or base class'错误
- C++为类中的枚举项设置值
- 模板类外部的长定义的替代项
- 如何在结构初始值设定项列表中实例化类
- 当键是虚拟继承中涉及的基类指针时,对 std::unordered_map 项的访问崩溃
- 访问类成员向量最后一项的正确方法
- 大括号括起来的初始值设定项列表中的短 c++ 类构造函数
- 如何在类的初始值设定项列表中初始化 std::array,而不对数组的大小进行硬编码
- 类成员和依赖项注入的对象与引用
- C2436 '{ctor}':构造函数初始值设定项列表中的成员函数或嵌套类
- C++如何在派生类上进行依赖项注入
- 将makefile中的一个项中的多个类分组
- C++11 默认类成员初始化与初始值设定项列表同时
- 具有显式初始值设定项的类的内存分配
- 如何在 C++ 中将 typedef 与类初始值设定项参数一起使用?
- 使用初始值设定项列表作为函数参数的类对象实现运算符 [] 的示例
- 无论如何,是否可以使用用户输入的类项名称来访问该项中的数据
- validinteger是某个enum类项(c++ 11)
- 赋给c++中对象类项的枚举值