Какой тип Enum в C ++ вы используете? - PullRequest
44 голосов
/ 20 октября 2008

Общеизвестно, что встроенные перечисления в 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: (Приятно иметь) Возможность перебора значений перечисления.

Ответы [ 11 ]

0 голосов
/ 08 июня 2009

Не уверен, что этот пост слишком поздно, но на GameDev.net есть статья, которая удовлетворяет всем, кроме 5-го пункта (возможность перебирать счетчики): http://www.gamedev.net/reference/snippets/features/cppstringizing/

Метод, описанный в статье, обеспечивает поддержку преобразования строк для существующих перечислений без изменения их кода. Если вам нужна только поддержка новых перечислений, я бы использовал Boost.Enum (упомянуто выше).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...