의 사용 부스트 :: 프리 프로세서는 다음과 같은 가능한 우아한 해결책을한다 :
1 단계 : 헤더 파일 포함 :
#include "EnumUtilities.h"
2 단계 : 다음 구문을 사용하여 열거 형 개체를 선언합니다.
MakeEnum( TestData,
(x)
(y)
(z)
);
3 단계 : 데이터 사용 :
요소 수 얻기 :
td::cout << "Number of Elements: " << TestDataCount << std::endl;
관련 문자열 가져 오기 :
std::cout << "Value of " << TestData2String(x) << " is " << x << std::endl;
std::cout << "Value of " << TestData2String(y) << " is " << y << std::endl;
std::cout << "Value of " << TestData2String(z) << " is " << z << std::endl;
관련 문자열에서 열거 형 값 가져 오기 :
std::cout << "Value of x is " << TestData2Enum("x") << std::endl;
std::cout << "Value of y is " << TestData2Enum("y") << std::endl;
std::cout << "Value of z is " << TestData2Enum("z") << std::endl;
포함 할 추가 파일없이 깔끔하고 간결 해 보입니다. EnumUtilities.h에서 작성한 코드는 다음과 같습니다.
#include <boost/preprocessor/seq/for_each.hpp>
#include <string>
#define REALLY_MAKE_STRING(x) #x
#define MAKE_STRING(x) REALLY_MAKE_STRING(x)
#define MACRO1(r, data, elem) elem,
#define MACRO1_STRING(r, data, elem) case elem: return REALLY_MAKE_STRING(elem);
#define MACRO1_ENUM(r, data, elem) if (REALLY_MAKE_STRING(elem) == eStrEl) return elem;
#define MakeEnum(eName, SEQ) \
enum eName { BOOST_PP_SEQ_FOR_EACH(MACRO1, , SEQ) \
last_##eName##_enum}; \
const int eName##Count = BOOST_PP_SEQ_SIZE(SEQ); \
static std::string eName##2String(const enum eName eel) \
{ \
switch (eel) \
{ \
BOOST_PP_SEQ_FOR_EACH(MACRO1_STRING, , SEQ) \
default: return "Unknown enumerator value."; \
}; \
}; \
static enum eName eName##2Enum(const std::string eStrEl) \
{ \
BOOST_PP_SEQ_FOR_EACH(MACRO1_ENUM, , SEQ) \
return (enum eName)0; \
};
몇 가지 제한이 있습니다. 예를 들어 boost :: preprocessor의 제한이 있습니다. 이 경우 상수 목록은 64 개 요소보다 클 수 없습니다.
동일한 논리에 따라 희소 열거 형을 생성 할 수도 있습니다.
#define EnumName(Tuple) BOOST_PP_TUPLE_ELEM(2, 0, Tuple)
#define EnumValue(Tuple) BOOST_PP_TUPLE_ELEM(2, 1, Tuple)
#define MACRO2(r, data, elem) EnumName(elem) EnumValue(elem),
#define MACRO2_STRING(r, data, elem) case EnumName(elem): return BOOST_PP_STRINGIZE(EnumName(elem));
#define MakeEnumEx(eName, SEQ) \
enum eName { \
BOOST_PP_SEQ_FOR_EACH(MACRO2, _, SEQ) \
last_##eName##_enum }; \
const int eName##Count = BOOST_PP_SEQ_SIZE(SEQ); \
static std::string eName##2String(const enum eName eel) \
{ \
switch (eel) \
{ \
BOOST_PP_SEQ_FOR_EACH(MACRO2_STRING, _, SEQ) \
default: return "Unknown enumerator value."; \
}; \
};
이 경우 구문은 다음과 같습니다.
MakeEnumEx(TestEnum,
((x,))
((y,=1000))
((z,))
);
사용법은 위와 비슷합니다 (이전 구문에서 추정 할 수있는 eName ## 2Enum 함수 제외).
Mac과 Linux에서 테스트했지만 boost :: preprocessor는 완전히 이식 가능하지 않을 수 있습니다.