Я предпочитаю следующий подход (код ниже).
Он решает проблему «загрязнения пространства имен», но он также намного более безопасен для типов (вы не можете назначать и даже сравнивать два различных перечисления или ваше перечисление с любыми другими встроенными типами и т. Д.).
struct Color
{
enum Type
{
Red, Green, Black
};
Type t_;
Color(Type t) : t_(t) {}
operator Type () const {return t_;}
private:
//prevent automatic conversion for any other built-in types such as bool, int, etc
template<typename T>
operator T () const;
};
Использование:
Color c = Color::Red;
switch(c)
{
case Color::Red:
//некоторый код
break;
}
Color2 c2 = Color2::Green;
c2 = c; //error
c2 = 3; //error
if (c2 == Color::Red ) {} //error
If (c2) {} error
Я создаю макрос для облегчения использования:
#define DEFINE_SIMPLE_ENUM(EnumName, seq) \
struct EnumName {\
enum type \
{ \
BOOST_PP_SEQ_FOR_EACH_I(DEFINE_SIMPLE_ENUM_VAL, EnumName, seq)\
}; \
type v; \
EnumName(type v) : v(v) {} \
operator type() const {return v;} \
private: \
template<typename T> \
operator T () const;};\
#define DEFINE_SIMPLE_ENUM_VAL(r, data, i, record) \
BOOST_PP_TUPLE_ELEM(2, 0, record) = BOOST_PP_TUPLE_ELEM(2, 1, record),
Использование:
DEFINE_SIMPLE_ENUM(Color,
((Red, 1))
((Green, 3))
)
Некоторые ссылки:
- Херб Саттер, Jum Hyslop, C / C ++ Users Journal, 22 (5), май 2004 г.
- Херб Саттер, Дэвид Э. Миллер, Бьярн Страуструп, сильно типизированные перечисления (редакция 3), июль 2007 г.