Точная форма того, что вы хотите, насколько я знаю, невозможна. Как сказал Нил, имена для нас просто люди; компилятор имеет дело со значениями.
Тем не менее, вы можете создать утилиту для присвоения имен перечислениям. Вот пример:
#define ENUM_NAMES_BEGIN(pType) \
std::ostream& operator<<(std::ostream& pStream, pType pValue) \
{ \
switch (pValue) \
{
#define ENUM_NAMES_CASE_NAMED(pValue, pName) \
case (pValue): \
pStream << (pName); \
break;
#define ENUM_NAMES_CASE(pValue) ENUM_NAMES_CASE_NAMED(pValue, #pValue)
#define ENUM_NAMES_END(pDefault) \
default: \
pStream << (pDefault); \
} \
\
return pStream; \
}
Вы бы использовали его так:
#include <iostream>
enum Days
{
Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday
};
enum NotNamed
{
DontTry, ImNotnamed
};
ENUM_NAMES_BEGIN(Days)
ENUM_NAMES_CASE(Sunday)
ENUM_NAMES_CASE(Monday)
ENUM_NAMES_CASE(Tuesday)
ENUM_NAMES_CASE(Wednesday)
ENUM_NAMES_CASE(Thursday)
ENUM_NAMES_CASE(Friday)
ENUM_NAMES_CASE_NAMED(Saturday, "Saturday: Fun day!")
ENUM_NAMES_END("")
int main()
{
Days d = Saturday; // or whatever
NotNamed n = ImNotnamed;
std::cout << "Day: " << d << std::endl;
std::cout << "Not Named: " << n << std::endl;
}
Попытка его с типом, который "безымянный", возвращает его числовое значение.
Обратите внимание, что здесь нет никакого перечисления enum; Вы можете использовать это, например, для именования целочисленных значений. Если бы вы это сделали, operator<<
было бы неоднозначно.
Если вы можете использовать Boost, используйте черту их типа is_enum
(что довольно сложно) и статически утверждают, что так оно и есть. Для этого изменения будут:
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_enum.hpp>
#define ENUM_NAMES_BEGIN(pType) \
std::ostream& operator<<(std::ostream& pStream, pType pValue) \
{ \
BOOST_STATIC_ASSERT(boost::is_enum<pType>::value); \
switch (pValue) \
{
Теперь, если тип не является перечислением, ошибка компиляции, по крайней мере, указывает на строку, где вы пытаетесь определить имена перечисления.