Я также склоняюсь к тому, чтобы обернуть свои списки в классах.
Как сообщил Ричард Корден, преимущество класса состоит в том, что он является типом в смысле c ++, и поэтому вы можете использовать его с шаблонами.
У меня есть специальный класс toolbox :: Enum для моих нужд, который я специализирую для каждого шаблона, который предоставляет базовые функции (в основном: отображение значения enum в std :: string, чтобы облегчить чтение операций ввода-вывода).
Мой маленький шаблон также имеет дополнительное преимущество - он действительно проверяет допустимые значения. Компилятор довольно слабо проверяет, действительно ли значение находится в перечислении:
typedef enum { False: 0, True: 2 } boolean;
// The classic enum you don't want to see around your code ;)
int main(int argc, char* argv[])
{
boolean x = static_cast<boolean>(1);
return (x == False || x == True) ? 0 : 1;
} // main
Меня всегда беспокоило, что компилятор не поймает это, так как у вас осталось значение enum, которое не имеет смысла (и которое вы не ожидаете).
Аналогично:
typedef enum { Zero: 0, One: 1, Two: 2 } example;
int main(int argc, char* argv[])
{
example y = static_cast<example>(3);
return (y == Zero || y == One || y == Two) ? 0 : 1;
} // main
Еще раз main вернет ошибку.
Проблема в том, что компилятор поместит перечисление в наименьшее доступное представление (здесь нам нужно 2 бита) и что все, что помещается в это представление, считается допустимым значением.
Существует также проблема, заключающаяся в том, что иногда вместо переключателя вы предпочитаете цикл с возможными значениями, чтобы вам не приходилось изменять все переключатели каждый раз, когда вы добавляете значение в перечисление.
В общем, мой маленький помощник действительно облегчает вещи для моих перечислений (конечно, это добавляет некоторые накладные расходы), и это возможно только потому, что я вкладываю каждое перечисление в свою собственную структуру:)