2011-01-20 4 views
18

매크로에 포함 파일 이름을 생성하려고합니다. 이것은 C++에 대한 법률 있어야하는데 :매크로에 포함 파일 이름 생성

#define INCLUDE_FILE "module_impl_win.hpp" 
#include INCLUDE_FILE 

이 잘 작동하지만 최대한 빨리 생성 된 파일 이름으로 시도로는

#define INCLUDE_FILE(M) M##"_impl_win.hpp" 
#include INCLUDE_FILE("module") 

를 컴파일도 실패한 실제로 나를 MSVC2010

에 경고 제공

C4067 경고 : 예기치 않은 토큰 다음 처리기 지시문 - 예상 Newlin는

이지만 파일을 포함하지 않습니다.

무엇이 문제입니까? 어떻게 제거 할 수 있습니까?

답변

18

헬퍼 인용 매크로를 사용하면됩니다. 이런 식으로 뭔가 당신이 원하는 당신을 줄 것이다 :

#define QUOTEME(M)  #M 
#define INCLUDE_FILE(M) QUOTEME(M##_impl_win.hpp) 

#include INCLUDE_FILE(module) 
+1

이 방법을 사용할 때는주의해야합니다.'_impl_win'은 식별자 토큰이며, 밑줄로 시작하고 매크로 네임 스페이스에 있기 때문에 구현에 예약되어 있습니다. 앞의'_'을 떼어 내고 따로 연결해야합니다. 그러나 머리 꼭대기에서'_' 그 자체가 예약 된 식별자이기 때문에 어떻게해야할지 모르겠습니다. –

+1

그런데 어떻게 휴대용입니까? – ledokol

+0

@James McNellis : Standard는 밑줄이있는 이름과 대문자 (또는 밑줄이 두 개인 이름) 만 보유합니다. – ledokol

3

문제는 결국 코드는 다음과 같이 것입니다 :

#include "module""_impl_win.hpp" 

이 같은 경고를 생성하고 당신이보고있는 오류하지만 약간 더 확실한 방법으로.

컴파일러는 해당 구문을 허용하지만 전처리 기는 허용하지 않습니다.

나는 당신이하려는 일을하기위한 제안이 없습니다. 개인적으로 시각적으로 코드를 탐색하기가 어려워지고 많은 편집자가 코드를 빠르게 탐색하지 못하게하기 때문에 이러한 유형의 매크로를 사용하고 싶지 않습니다.

+0

감사합니다. 그런 식으로 문자열을 연결한다는 것을 몰랐습니다. #ifdef ... #endif와 함께 플랫폼 특정 헤더를 포함하는 수백 개의 파일이 있다고 상상해보십시오. 내일이면 또 하나의 플랫폼에 대한 지원을 추가 할 것이고 하나의 매크로를 편집하고 플랫폼 특정 구현 파일을 추가하는 대신이 파일을 모두 편집해야 할 것입니다. 그거 슬프다. – ledokol

+0

@ledokol : 플랫폼 별 기능을 별도의 헤더와 다른 곳에 포함되지 않은 소스 파일로 나눌 수없는 이유는 무엇입니까? 비교적 작은 파일 세트에 플랫폼 특정 기능과 플랫폼 종속 기능을 쉽게 통합 할 수 있어야합니다. –

+0

PIMPL이 플랫폼 특정 코드를 분리하는 데 사용되지 않는 이유는 무엇입니까? 음, 어디서나 사용할 수는 없습니다. 플랫폼 특정 구현 클래스 선언이 필요한 많은 템플릿 클래스가 있습니다. 그래서 헤더와 구현 파일로 나누어야합니다. – ledokol

3

또한 처리기, 특히 BOOST_PP_STRINGIZE/BOOST_PP_CAT 매크로 부스트 사용할 수 있습니다

#include <boost/preprocessor/cat.hpp> 
#include <boost/preprocessor/stringize.hpp> 

#define INCLUDE_FILE(M) BOOST_PP_STRINGIZE(BOOST_PP_CAT(M, _impl_win.hpp)) 

// expands to: #include "module_impl_win.hpp" 
#include INCLUDE_FILE(module) 

(참조 C Macro - DynamiC#include)

참고이 @ Andrew의 답과 같은 문제가 있습니다 (밑줄 = 예비 식별자).