2009-12-18 4 views
5

매크로가 있는데, 인수 중 하나가 네임 스페이스 범위를 지정하지 않고 주어진 enum 값입니다. 그러나 어딘가에 매크로에 액세스해야합니다 (분명히 네임 스페이스를 정의해야합니다). 그러나 네임 스페이스 이름을 템플릿 매개 변수와 연관시킬 수 없습니다. 다음 샘플 코드에서 컴파일러는 pasting :: and Val doesnt give a valid preprocessor token (getter와 getVal을 연결하는 데는 문제가 없습니다)라는 오류가 발생합니다.Concat 매크로 인수와 네임 스페이스

namespace TN 
{ 
    enum Info 
    { 
     Val = 0 
    }; 
} 

#define TEST(a) TN::Info get ## a(){return TN::##a;} 
TEST(Val) 

그래서 두 번 (예를 들어 #define TEST(a,b) TN::Info get ## a(){return b;}) 사용되는 값을 또 다른 인수를 사용하여 기본적으로 지정하지 않고이 일을 할 수있는 방법은 무엇입니까?

답변

10

##은 토큰 붙여 넣기 연산자입니다. 즉, 여러 토큰 비트에서 하나의 토큰을 만들어야하며 컴파일러에서 말한 것처럼 ::Val은 하나의 토큰이 아니며 두 개의 토큰입니다.

왜 두 번째가 필요하다고 생각하십니까? ##? 이게 뭐가 잘못 됐어.

#define TEST(a) TN::Info get ## a() { return TN::a; } 
+0

분명히 나는 ​​복잡하게 생각하고있다. 감사합니다. – Grizzly

+0

@ 그리즐리 : 역설적이게, 반대! 매크로는 기본적으로 찾기 및 바꾸기 텍스트 대체이기 때문에 내 첫 번째 본능은 연결해야합니다. 그것은 당신이 그들이 이것보다 더 복잡하다는 것을 깨달을 때입니다. (이것들은 _tokens_에서 작동하고 우리의 두뇌는 그렇지 않습니다) 이런 문제가 발생합니다. :) –

3

두 항목을 연결하고 결과를 단일 토큰 (예 : 식별자)으로 처리하도록하려면 ## 만 사용하십시오.

매크로에서 get과 내용을 a으로 붙여 넣어 식별자를 구성하려고 시도 했으므로 ##의 첫 번째 사용은 정확하지만 ##의 두 번째 사용은 단지 만들고 싶어하므로 a의 내용에서 식별자가 나오고 :: 연산자는 그 것과 별개의 엔티티입니다. GCC는이 점에 대해 불평 할 것입니다 (그러나 MSVC++ 대응).

#define TEST(a) TN::Info get ## a(){return TN::a;} 

.