问题描述
众所周知,C++ 中的内置枚举不是类型安全的.我想知道那里使用了哪些实现类型安全枚举的类......我自己使用以下自行车",但它有点冗长和有限:
It is common knowledge that built-in enums in C++ are not typesafe.I was wondering which classes implementing typesafe enums are used out there...I myself use the following "bicycle", but it is somewhat verbose and limited:
typesafeenum.h:
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:
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;
添加:我想我应该更具体地说明要求.我会试着总结一下:
Addition:I think I should have been more specific about the requirements. I'll try to summarize them:
优先级 1:将枚举变量设置为无效值应该是不可能的(编译时错误),没有例外.
Priority 1: Setting an enum variable to an invalid value should be impossible (a compile-time error) with no exceptions.
优先级 2:应该可以通过单个显式函数/方法调用将枚举值转换为 int 值.
Priority 2: Converting an enum value to/from an int should be possible with a single explicit function/method call.
优先级 3:尽可能简洁、优雅和方便的声明和使用
Priority 3: As compact, elegant and convenient declaration and usage as possible
优先级 4:将枚举值与字符串相互转换.
Priority 4: Converting enum values to and from strings.
优先级 5:(很高兴)可以迭代枚举值.
Priority 5: (Nice to have) Possibility to iterate over enum values.
推荐答案
我目前正在研究 Boost Vault(文件名 enum_rev4.6.zip
).尽管它从未正式提交以包含在 Boost 中,但它可以按原样使用.(文档缺乏,但通过清晰的源代码和良好的测试来弥补.)
I'm currently playing around with the Boost.Enum proposal from the Boost Vault (filename enum_rev4.6.zip
). Although it was never officially submitted for inclusion into Boost, it's useable as-is. (Documentation is lacking but is made up for by clear source code and good tests.)
Boost.Enum 允许你像这样声明一个枚举:
Boost.Enum lets you declare an enum like this:
BOOST_ENUM_VALUES(Level, const char*,
(Abort)("unrecoverable problem")
(Error)("recoverable problem")
(Alert)("unexpected behavior")
(Info) ("expected behavior")
(Trace)("normal flow of execution")
(Debug)("detailed object state listings")
)
并让它自动扩展为:
class Level : public boost::detail::enum_base<Level, string>
{
public:
enum domain
{
Abort,
Error,
Alert,
Info,
Trace,
Debug,
};
BOOST_STATIC_CONSTANT(index_type, size = 6);
Level() {}
Level(domain index) : boost::detail::enum_base<Level, string>(index) {}
typedef boost::optional<Level> optional;
static optional get_by_name(const char* str)
{
if(strcmp(str, "Abort") == 0) return optional(Abort);
if(strcmp(str, "Error") == 0) return optional(Error);
if(strcmp(str, "Alert") == 0) return optional(Alert);
if(strcmp(str, "Info") == 0) return optional(Info);
if(strcmp(str, "Trace") == 0) return optional(Trace);
if(strcmp(str, "Debug") == 0) return optional(Debug);
return optional();
}
private:
friend class boost::detail::enum_base<Level, string>;
static const char* names(domain index)
{
switch(index)
{
case Abort: return "Abort";
case Error: return "Error";
case Alert: return "Alert";
case Info: return "Info";
case Trace: return "Trace";
case Debug: return "Debug";
default: return NULL;
}
}
typedef boost::optional<value_type> optional_value;
static optional_value values(domain index)
{
switch(index)
{
case Abort: return optional_value("unrecoverable problem");
case Error: return optional_value("recoverable problem");
case Alert: return optional_value("unexpected behavior");
case Info: return optional_value("expected behavior");
case Trace: return optional_value("normal flow of execution");
case Debug: return optional_value("detailed object state listings");
default: return optional_value();
}
}
};
它满足您列出的所有五个优先事项.
It satisfies all five of the priorities which you list.
这篇关于您在 C++ 中使用哪种类型安全枚举?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!