이름

2014-02-26 1 views
1

이 정의하는 수정 프로그램입니다, 나는 (이름

#define X_ERR_OK (0) 
#define X_ERR_FOO (816) 
#define X_ERR_OTHER (842) 
// .. and more 

오류 코드의 이름을 반환 조금 기능이 그들에게 내 코드를 (타사 lib 디렉토리)를 변경할 수 없습니다 , 나는 그것을 바꿀 수있다)

#define X_ERR_CASE(e) case e: return #e 
const char* err_name(int err) { 
    switch(err) { 
    X_ERR_CASE(X_ERR_OK); 
    X_ERR_CASE(X_ERR_FOO); 
    X_ERR_CASE(X_ERR_OTHER); 
    } 
    return "<unknown>"; 
} 

이것은 작동한다. 지금은 스마트 LIB를 boost.preprocessor 발견하고 그것을 사용하려고 :

#define XX_ERR_CASE(r, _, e) case e: return BOOST_PP_STRINGIZE(e); 
#define XX_ERRORS(seq) \ 
    const char* err_name2(int err) { \ 
     switch(err) { \ 
     BOOST_PP_SEQ_FOR_EACH(XX_ERR_CASE, _, seq) \ 
     } \ 
     return "<unknown>"; } 

XX_ERRORS(
    (X_ERR_OK) 
    (X_ERR_FOO) 
    (X_ERR_OTHER) 
) 

을하지만 출력이 정의하지만, 수의 이름이 아니기 때문에이 아니라 일을한다. 예를 들어 내가 갖고 싶어 : X_ERR_FOO를,하지만 난 X_ERR_FOOerr_name(816)를 호출 얼마나 BOOST_PP_SEQ_HEAD(((816)) ((842)) (nil))

을 얻을 XX_ERR_CASE

#define XX_ERR_CASE(r, _, e) case e: return #e; 

에 내가 변경하면 나는 (816)

를 얻을?

+2

불행히도 함수와 비슷한 매크로의 인수 안에 포함 된 매크로는 매개 변수의 * 대체 * 전에 * 대체되므로 매크로 이름을 전달할 수 없습니다. 그러나 확장을 '#'또는 '##'로 금지 할 수 있습니다. 나는. 당신은'#define E (M) (E, #E)'를 정의하고이를 사용하여 시퀀스를'E (X_ERR_OK) E (X_ERR_FOO)'와 같이 생성한다. [실례 예.] (http://coliru.stacked-crooked.com/a/bf245740a9d01bd3) – dyp

+1

http://coliru.stacked-crooked.com/a/6401e0af6b75e700 – llonesmiz

+0

그 작품! 감사합니다 dyp 및 cv_and_he –

답변

1

나는 이것이 받아 들일 수 있을지 의심 스럽지만 어쨌든 도움이 될 것이라고 생각합니다. 이 접근 방식을 사용하면 XX_ERRORS으로 전화하는 방식을 변경해야하며 그 인수에는 X_ 접두어가 제거되어야합니다.

#include <iostream> 
#include <boost/preprocessor.hpp> 

#define X_ERR_OK (0) 
#define X_ERR_FOO (816) 
#define X_ERR_OTHER (842) 


#define XX_ERR_CASE(r, _, e) case BOOST_PP_CAT(X_,e): return "X_" BOOST_PP_STRINGIZE(e); 
#define XX_ERRORS(seq) \ 
    const char* err_name2(int err) { \ 
     switch(err) { \ 
     BOOST_PP_SEQ_FOR_EACH(XX_ERR_CASE, _, seq) \ 
     } \ 
     return "<unknown>"; } 

XX_ERRORS(
    (ERR_OK) 
    (ERR_FOO) 
    (ERR_OTHER) 
) 

int main() 
{ 
    std::cout << err_name2(816) << std::endl; 
} 
+0

만약 내가 용의자로,이 대답은 허용되지 않습니다, 그냥 의견을 남겨주 그리고 내가 그것을 제거합니다. – llonesmiz

+0

이것은 정말 좋은 생각입니다. 놀라운 - 작동합니다! '받아 들일 수 없습니다'.. 저는 생각해야합니다. 아마도 누군가 다른 대답을 가지고있을 것입니다. 제거하지 마십시오. 대신 사용할 수 있습니다. –