Общеизвестно, что встроенные перечисления в 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. Установка переменной enum на недопустимое значение должна быть невозможной (ошибка времени компиляции) без исключений.
Приоритет 2. Преобразование значения enum в / из int должно быть возможно с помощью одного явного вызова функции / метода.
Приоритет 3: максимально компактное, элегантное и удобное описание и использование
Приоритет 4. Преобразование значений перечисления в и из строк.
Приоритет 5: (Приятно иметь) Возможность перебора значений перечисления.