【发布时间】:2010-09-18 01:38:28
【问题描述】:
众所周知,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;
};
typesafeenum.cpp:
int TypesafeEnum::next_id = 1;
bool TypesafeEnum::operator== (const TypesafeEnum& right) const
{ return id == right.id; }
bool TypesafeEnum::operator!= (const TypesafeEnum& right) const
{ return !operator== (right); }
bool TypesafeEnum::operator< (const TypesafeEnum& right) const
{ return id < right.id; }
用法:
class Dialog
{
...
struct Result: public TypesafeEnum
{
static const Result CANCEL("Cancel");
static const Result OK("Ok");
};
Result doModal();
...
};
const Dialog::Result Dialog::Result::OK;
const Dialog::Result Dialog::Result::CANCEL;
补充: 我想我应该对要求更具体。我会尝试总结它们:
优先级 1:将枚举变量设置为无效值应该是不可能的(编译时错误),没有例外。
优先级 2:应该可以通过单个显式函数/方法调用将枚举值转换为 int。
优先级3:尽可能简洁、优雅、方便的声明和使用
优先级 4:将枚举值与字符串相互转换。
优先级 5:(很高兴)可以迭代枚举值。
【问题讨论】:
-
对不起,你用什么编译器? MSVC 2008 无法编译此示例。这 - static const 结果 CANCEL("Cancel"); - 看起来不像是有效的 C++ 代码...
-
@Stiver:抱歉耽搁了这么久,可能不再相关,但我仍然会回答:这是我的错误,我没有字符串的原始版本,我用螺栓固定了它们发帖前没有检查,对不起。正确的版本会将字符串传递给 cpp 文件中的枚举值的构造函数。
-
这是目前为止关于枚举和字符串的最佳问题。
-
我已将标签更改为 c++03,因为显式类型的枚举现在是 C++ 的一部分。请注意,在 C++2003 中已经“类型安全”的枚举。
标签: design-patterns enums enumeration type-safety c++03