프로그래머라면 누구나 enum값이 4byte 정수 자료형이라는 사실을 알고 있습니다.
switch( xxx ) // xxx 에는 정수 자료형만 올 수 있다는 것도 알고 있습니다.
switch( string )
{
   case "A_Case": ... break;
   case "B_Case": ... break;
}

이런식으로 switch 문에서도 문자열을 받고 싶을때가 많습니다.
혹은 enum 값을 1:1 매칭되는 문자열 값으로 변환하고 싶을때가 많습니다.

우연히 웹 서핑을 하던 중 http://eslife.tistory.com/entry/CC-enum-보다-나은-enum을 읽게 되었고,
약간의 팁을 보강하여 다음과 같이 정리 하였습니다.
namespace nsTerminalType
{
#define MAKE_STRING( X ) #X
#define IMPLEMENT_ENUM(enumType, enumValue) enumType##_##enumValue,
#define IMPLEMENT_DESC(enumType, enumValue) _T( MAKE_STRING( enumType##_##enumValue ) ),
#define IMPLEMENT_ENUM_TO_STRING(enumType)                                  \
    inline TCHAR* ToString( const enumType##& arg )                         \
    {                                                                       \
        return ( arg < enumType##_MAX ) ? ptszEnumTypeDesc[ arg ] : _T(""); \
    }                                                                       \
    inline TCHAR* GetEnumType() { return _T( MAKE_STRING( enumType ) ); }

    // enumType의 enum 값을 선언한다.( ..., MAX )
#define DECLARE_ENUM_LIST(ENUM_TYPE, ENUM_VALUES)    \
    ENUM_VALUES(ENUM_TYPE, GROUP)                    \
    ENUM_VALUES(ENUM_TYPE, CONNECTION)               \
    ENUM_VALUES(ENUM_TYPE, MAX)

    enum ETerminalType
    {
        DECLARE_ENUM_LIST( ETerminalType, IMPLEMENT_ENUM )
    };

    static TCHAR* ptszEnumTypeDesc[] = 
    {
        DECLARE_ENUM_LIST( ETerminalType, IMPLEMENT_DESC )
    };

    IMPLEMENT_ENUM_TO_STRING( ETerminalType )
};
위 문장이 전처리기 지시어로 도배(?)가 되어 있어서 가독성이 매우 떨어집니다.
잘 이해가 안가시는 분들을 위해서 한가지 팁을 알려 드리겠습니다.(전처리기 지시어를 자동 변환하는 방법 입니다.)
"C:\Program Files\Microsoft Visual Studio 8\VC\bin\cl.exe" 를 사용하시면 됩니다.
1. 헤더파일에서 #in clude 문을 모두 주석처리 합니다.
  (#include 문을 만나면 파일을 포함하려고 시도하다가 찾지 못하면 에러가 발생하고, 전처리기 지시문 변환을 실패합니다.)
2. c md(console 입력창)에서 다음과 같이 입력 합니다.
cl /EP /C test.h > c:\result.txt & notepad c:\result.txt
namespace nsTerminalType
{
    // enumType의 enum 값을 선언한다.( ..., MAX )
    enum ETerminalType
    {
        ETerminalType_GROUP, ETerminalType_CONNECTION, ETerminalType_MAX,
    };

    static TCHAR* ptszEnumTypeDesc[] = 
    {
        _T( "ETerminalType_GROUP" ), _T( "ETerminalType_CONNECTION" ), _T( "ETerminalType_MAX" ),
    };

    inline TCHAR* ToString( const ETerminalType& arg ) { return ( arg < ETerminalType_MAX ) ? ptszEnumTypeDesc[ arg ] : _T(""); }
};
전처리기 지시어가 깔끔하게 해석되어 나오는 것을 볼 수 있습니다.

이렇게 작성하면 enum 값을 문자열로 변환하고 싶을때,
TCHAR* pString = nsTerminalType::ToString( nsTerminalType::ETerminalType_GROUP )
이렇게 쓰시면,
TCHAR* pString = _T("ETerminalType_GROUP");
와 같은 결과를 얻으실 수 있습니다.

장점 1. namespace를 사용해서 인텔리센스를 적극적으로 활용할 수 있다.
장점 2. enum 자료형을 추가하면 그에 맞는 문자열이 등록된다.
(enum 값만 추가하고 문자열을 등록하지 않는 실수를 막을 수 있다.)
장점 3. 전처리기 지시어를 두려워하지 않아도 된다.(cl 명령어로 손쉽게 해석해서 보시면 됩니다.)
2009/01/07 21:23 2009/01/07 21:23

글 걸기 주소 : 이 글에는 트랙백을 보낼 수 없습니다

덧글을 달아 주세요

  1. TTF 2011/10/03 19:18 고유주소 고치기 답하기

    미리내 호스팅에서 rm, cp, ps 문장을 필터링해서 저장하지 못하도록 막아놨습니다.
    ㅠ_ㅠ
    게시물이 매끄럽지 못한 부분에 대해서 사과 드립니다.
    조만간 미리내 호스팅에서 답변 받고 수정하도록 하겠습니다.

    • TTF 2011/10/04 20:48 고유주소 고치기

      미리내 호스팅에서 수정해 주셨습니다. 감사합니다.