众所周知,C++中的内置枚举不是类型安全的.我想知道实现类型安全枚举的哪些类在那里使用...我自己使用以下"自行车",但它有点冗长和有限:
typesafeenum.h:
struct TypesafeEnum
{
// Construction:
public:
TypesafeEnum(): id (next_id++), name("") {}
TypesafeEnum(const std::string& n): id(next_id++), name(n) {}
// Operations:
public:
bool operator == (const TypesafeEnum& right) const;
bool operator != (const TypesafeEnum& right) const;
bool operator < (const TypesafeEnum& right) const;
std::string to_string() const { return name; }
// Implementation:
private:
static int next_id;
int id;
std::string name;
};
Run Code Online (Sandbox Code Playgroud)
typesafeenum.cpp:
int TypesafeEnum::next_id = 1;
bool TypesafeEnum::operator== (const TypesafeEnum& right) const
{ return id == right.id; }
bool TypesafeEnum::operator!= …
Run Code Online (Sandbox Code Playgroud) enum
C++中的类型是相当基本的; 它基本上只是为标签创建了一堆编译时值(可能具有适当的范围enum class
).
将相关的编译时常量分组在一起非常有吸引力:
enum class Animal{
DOG,
CAT,
COW,
...
};
// ...
Animal myAnimal = Animal::DOG;
Run Code Online (Sandbox Code Playgroud)
然而,它有各种各样的缺点,包括:
在这篇文章中,我试图创建一种解决这些缺点的类型.
一个理想的解决方案采用常量的编译时知识及其与字符串的关联的概念,并将它们组合成一个类似于scoped-enum的对象,可以通过enum id和enum string name进行搜索.最后,结果类型将使用尽可能接近枚举语法的语法.
在这篇文章中,我将首先概述其他人为各个部分所尝试的内容,然后介绍两种方法,一种完成上述方法,但由于静态成员的初始化顺序而具有未定义的行为,另一种解决方案不那么漂亮语法但由于初始化顺序没有未定义的行为.
关于获取枚举中的项目数量(1 2 3)以及网上提出的大量其他问题(4 5 6)等,有很多问题.而且普遍的共识是,没有确定 -火的方式做到这一点.
仅当您强制执行枚举值为正且增加时,以下模式才有效:
enum Foo{A=0, B, C, D, FOOCOUNT}; // FOOCOUNT is 4
Run Code Online (Sandbox Code Playgroud)
但是,如果您尝试编码某种需要任意值的业务逻辑,则很容易被破坏:
enum Foo{A=-1, B=120, C=42, D=6, FOOCOUNT}; // ????
Run Code Online (Sandbox Code Playgroud)
所以Boost的开发人员试图用Boost.Enum来解决这个问题,Boost.Enum使用了一些相当复杂的宏来扩展到一些至少会给你大小的代码.
在迭代枚举中有一些尝试; 可以迭代的类似枚举的对象,理论上允许隐式大小计算,甚至在[7](7 8 9,...)的情况下明确允许
尝试实现这一点通常会导致自由浮动函数和使用宏来适当地调用它们.(8 …
在C++中使用连续值迭代枚举的首选简单方法是什么?我之前发现了关于这个主题的SO问题,其中涉及创建自定义operator++
等,但这看起来有点矫枉过正.到目前为止,我提出的最好的是:
enum {
FOO,
BAR,
BLECH,
NUM_ENUMS
} MyEnum;
//for (MyEnum m = FOO; m < NUM_ENUMS; ++m) // compile error
// ...
//for (MyEnum m = FOO; m < NUM_ENUMS; m = m + 1) // compile error
// ...
for (MyEnum m = FOO; m < NUM_ENUMS; m = MyEnum(m + 1)) // OK ?
...
Run Code Online (Sandbox Code Playgroud)
从编码风格的角度看这是否合理,是否可能产生警告(g++ -Wall ...
对此感到高兴)?
声明如下:
enum DrawBoldMode : unsigned
{
DBM_NONE = 0,
DBM_ITEM = 1<<0, // bold just the nearest line
DBM_SECTION = 1<<1, // bold all lines in the same section
DBM_LINETYPE = 1<<2, // bold all lines of the same line type
DBM_POINTAGE = 1<<3, // bold all lines of the same line type
};
Run Code Online (Sandbox Code Playgroud)
如何导出DrawBoldMode的基础类型(即无符号)?
我应该如何在C++ 11中循环枚举类?我希望我仍然不必添加END的最终枚举值,但我无法使基于范围的循环工作.
当我尝试编译以下代码时发生编译器错误:
for(binary_instructions_t &inst: BinaryInstructions){
}
Run Code Online (Sandbox Code Playgroud)
BinaryInstructions
是这个枚举类:
typedef unsigned int binary_instructions_t;
enum class BinaryInstructions : binary_instructions_t
{
END_OF_LAST_INSTR = 0x0,
RESET,
SETSTEP,
START,
STOP,
ADD,
REMOVE,
};
Run Code Online (Sandbox Code Playgroud)
我应该被允许使用枚举类中的项目来"循环"基于循环吗?或者我在该范围内巧妙地误解了基于循环是用于搜索数组的内容而不是像枚举类这样的东西?
我也尝试过:在实例中创建实例并进行搜索:
BinaryInstructions bsInstance;
for(binary_instructions_t &inst : bsInstance){
}
Run Code Online (Sandbox Code Playgroud)
但没有雪茄......提前谢谢,
c++ ×5
c++11 ×3
enums ×3
for-loop ×2
c++03 ×1
enum-class ×1
enumeration ×1
templates ×1
type-safety ×1