2017-10-23 14 views
0

매크로를 확장하여 응용 프로그램에 사용되는 typedef를 빌드 할 수 있어야합니다. 매크로는 간단한 typedef를 만듭니다. 내가 가지고있는 질문은 어떻게해야합니까? __VA_ARGS__ (즉, 호출을 더 멀리 내려 받겠습니까?) 많은 매크로를 통과 할 때 어떻게 행동해야하는지, 어떻게하면 다른 결과가 발생하는지 알 수있는 방법을 알 수 있습니다. 고등 주문 매크로를 만들 때 문제가 발생했습니다. DERIVED 매크로. C 전처리 (MSVC++, MSVC)의매크로를 올바르게 확장하는 방법은 무엇입니까?

#define DERIVED0()   rtti::impl::BaseTypedefList<rtti::impl::null> 
#define DERIVED1(T1)  rtti::impl::BaseTypedefList<T1, DERIVED0()> 
#define DERIVED2(T1, T2) rtti::impl::BaseTypedefList<T1, DERIVED1(T2)> 
#define BUILD(count, ...) DERIVED##count(__VA_ARGS__) 

// inside the classes 
#define CLASS_BODY(count, ...) typedef BUILD(count, __VA_ARGS__) BaseClassList; 

// example usages 
CLASS_BODY(0)     // WORKS 
CLASS_BODY(1, MeshRenderer)  // WORKS 
CLASS_BODY(2, Renderer, Object) // ERROR 
+0

MSVS를 사용하고 있습니까? –

+0

@HWalters 예 MSVS를 사용 중입니다 – Matthew

답변

1

마이크로 소프트 비주얼 스튜디오 버전은 다른 하나의 토큰으로 청크 분할 된 여러 일련의 토큰 될 엔티티의 독특한 개념을 가지고있다. 이것은 가변성 매크로를 확장 할 때 특히 효과적입니다. __VA_ARGS__은 쉼표가 포함 된 확장 인 경우에도 항상 단일 토큰으로 확장됩니다. 이 동작은 Microsoft 전 처리기에 특유한 것입니다. 특히

, CLASS_BODY(2, Renderer, Object)의 호출 동안, 당신은 호출하고 있습니다 :

BUILD(2, Renderer, Object) 

을 기술적으로 여기 Renderer, Object 한 토큰이지만, 시점에서 중요하지 않습니다. 여기서 인수를 식별하는 동안 class2...Renderer, Object으로 일치합니다. 인수 대체하는 동안,이 독특한 뭔가가된다 :

DERIVED##count(Renderer, Object) 

충분히 무해 보이지만, 독특한 것은 Renderer, Object 일괄 한 토큰 것입니다. 쉼표는 구분 기호로 처리되지 않습니다.

DERIVED2(Renderer, Object) 

... 다음 DERIVED2가 호출 : 우리가 붙여 넣기를 통해 산책 후 의미는 ... 잠시 후 볼 수 있습니다. 여기에서 인수 식별은 T1Renderer, Object을 일치시킵니다. T2는 매달려 있습니다. 그것은 일치하지 않습니다. 그러면 전 처리기 오류가 발생합니다.

일반적으로 어림짐작은 대체 목록에서 __VA_ARGS__을 사용할 때마다 확장 단계를 적용하는 것입니다. 적어도 여러 개의 전 처리기 토큰으로 구문 분석되는 여러 매개 변수를 사용하는 경우 (실제로 이상한 이유로 이 행동을 원하지만, 그런 경우에는 MSVS 특질에 얽매여있을 것입니다.) 간접의이 양식이 작동되는 시간의 99 % : 기회에

#define EVAL(...) __VA_ARGS__ 
#define BUILD(count, ...) EVAL(DERIVED##count(__VA_ARGS__)) 

이 같은 일을 할 수 있습니다 :

#define CALL(X,Y) X Y 
#define BUILD(count, ...) CALL(DERIVED##count,(__VA_ARGS__)) 

어느 쪽이 특정 경우에 작동합니다.

+0

이것은 완벽하게 작동했습니다 !!!! 매크로가 매우 다른 방식으로 작동한다는 것은 매우 짜증나는 일입니다. – Matthew