2016-11-09 10 views
4

필자는 함수와 비슷한 매크로에 두 개의 템플릿 인수가있는 유형을 제공하면 컴파일러가 불만을 제기하는 것에 놀랐습니다.괄호 안에있는 템플릿 인수 목록에서 쉼표를 "도용"하는 것은 함수와 같은 매크로에 적합합니까?

이 (개념적으로 유사한) 예제 코드 :

template<typename T> struct foo{}; 
template<typename T, U> struct bar{}; 
#define p(x) printf("sizeof(" #x ") = %u\n", sizeof(x)); 

int main() 
{ 
    p(foo<int>);  // works, of course 
    p(bar<int,int>); // does not work 
    p((bar<int,int>)); // does not work either 
    return 0; 
} 

는 GCC (6.2.0)이 macro "p" passed 2 arguments, but takes just 1 불평한다.

글쎄, 전처리 기는 전처리 기 텍스트 대체를하고있다. 템플릿이나 언어의 다른 모든 규칙을 이해하는 실제 C++ 컴파일러는 아니다.

아마도 전 처리기가 꺾쇠 괄호를 인식 할 것이라고 예상하여 너무 많이 묻습니다.하지만 적어도 괄호는 명시 적으로 사양에 언급되어 있습니다.

16.3 (단락 10-12)은 바운드 된 토큰 시퀀스를 한정하는 가장 바깥 쪽 괄호를 나타냅니다. "가장 바깥 쪽"인 단어은 전 처리기가 인식 할 수있는 (바깥 쪽이 아닌) 괄호가있을 수 있음을 암시합니다.
또한, 명시 적으로 뿐만 아니라 "일치 왼쪽과 오른쪽 괄호 쌍의 중간에 건너 뛰는"상태 "일치하는 내부 괄호 사이에 쉼표 전처리 토큰을 하지 별도의 인수" - 내가 제대로 읽고 있어요 경우 있음을 의미 , 적어도 마지막 줄 는 나의 이해의 패스가되어야한다.

무엇이 잘못 되었습니까?

+0

매크로가 일반 텍스트 처리를 수행하고 확장 할 대상을 확인하십시오. –

답변

6

p((bar<int,int>))은 하나의 매크로 인수 인 (bar<int,int>)을 사용하여 p 매크로의 유효한 호출입니다. 지금까지의 귀하의 이해가 정확합니다.

불행히도 확장에는 sizeof((bar<int,int>))이 포함되고 sizeof에는 이중 괄호 입력을 허용하지 않습니다.

Variadic 매크로 (C++ 11)는 대안으로 잘 작동합니다.

#define p(...) printf("sizeof(" #__VA_ARGS__ ") = %u\n", sizeof(__VA_ARGS__)); 
+0

설명해 주셔서 감사합니다. Variadic 매크로가 실제로 작동합니다. – Damon