如何在粘贴之前保证参数的完全宏扩展?

Ane*_*ton 7 c++ macros c-preprocessor

我有一个普通的宏:

#define mSwitch( Root, Case )  Root##_Case_##Case

#define mSpecialDisplay( what, Val )  mSwitch(mSpecialDisplay,what)(Val)
#define mSpecialDisplay_Case_Int(Val)    ...do stuff
#define mSpecialDisplay_Case_Float(Val)  ...do stuff
...more special cases
Run Code Online (Sandbox Code Playgroud)

如何保证变量Case在粘贴之前完全展开mSwitch

如果mSwitch传递一个文字值,它工作正常,但如果有多个间接层或中间操作,mSwitch最终会在完全展开之前粘贴其中一个.

我正在使用MSVC 2005.

有没有一种简单的方法可以确保参数在粘贴完成之前完全展开?

谢谢


好吧,举一个例子可能并不难:

  #define mMDebugInfo( ... ) mMDebugExp( mMDebugInfo_( 0, __VA_ARGS__ ) )

  #define mMDebugInfo_( C, ... ) mMAritize( mMSwitch( mMDebugInfo, mMMetaTrait( Detect, __VA_ARGS__ ) ), (C, __VA_ARGS__) )

  #define mMDebugInfoRep( C, ... ) mMXP##C( mMDebugInfo_ )mMXP##C((mMIInc(C),__VA_ARGS__)) //(mMExpDo(mMGlue( mM, C)##DebugInfo_(mMIInc(C),__VA_ARGS__))

  #define mMDebugInfo1( C, ... ) mMAritize( mMSwitch( mMDebugInfo, mMMetaTrait( Detect, __VA_ARGS__ ) ), (mMIInc(C), __VA_ARGS__) )

  #define mMDebugInfo_Case_Nil(...) [Nil]

  #define mMDebugInfo_Case_CntArgs(C,I,...) 
mMDebugInfoRep(C,I),mMDebugInfoRep(C,__VA_ARGS__)
  #define mMDebugInfo_Case_PrnNull(C,I) [()]

  #define mMDebugInfo_Case_Prn(C,I)   ( mMDebugInfoRep(C,mMDPrn(I)) )

  #define mMDebugInfo_Case_ActFn(C,I) mMAritize( mMDebugInfo_Case_Fn, (C, I, mMTrait_Fn_mM##I) )

  #define mMDebugInfo_Case_PassFn(C,I) mMAritize( mMDebugInfo_Case_Fn, (C, mMTrait_Fn_mM##I) )

  #define mMDebugInfo_Case_Fn( C,Name, Reg, ArgCnt, PArgs ) [Name:ArgCnt]( mMAritize( mMSwitch( mMDebugInfo_Case_Fn, ArgCnt ), (C, mMDPrn( PArgs ) )) )

  #define mMDebugInfo_Case_Fn_Case_V(C, _1, ...) mMDebugInfoRep(C, _1), mMDebugInfoRep(C, __VA_ARGS__)

  #define mMDebugInfo_Case_Fn_Case_0(...) [Nil]

  #define mMDebugInfo_Case_Fn_Case_1(C, _1, ...) mMDebugInfoRep(C, _1)

  #define mMDebugInfo_Case_Fn_Case_2(C, _1, _2, ...) mMDebugInfoRep(C, _1), mMDebugInfoRep(C, _2)

  #define mMDebugInfo_Case_Fn_Case_3(C, _1, _2, _3, ...) mMDebugInfoRep(C, _1), mMDebugInfoRep(C, _2), mMDebugInfoRep(C, _3)  

  #define mMDebugInfo_Case_Fn_Case_4(C, _1, _2, _3, _4, ...) mMDebugInfoRep(C, _1), mMDebugInfoRep(C, _2), mMDebugInfoRep(C, _3), mMDebugInfoRep(C, _4)

  #define mMDebugInfo_Case_Int(C,I)   [Num:I]

  #define mMDebugInfo_Case_Digit(C,I) [Dig:I] 

  #define mMDebugInfo_Case_Bool(C,I)  [Bin:I]

  #define mMDebugInfo_Case_CCode(C,I) [CCd:I]

  #define mMDebugInfo_Case_UToken(C,I) [UT:I]
Run Code Online (Sandbox Code Playgroud)

这是调试代码,递归解析嵌套表达式没有问题,如:

DebugInfo( BInt( BNot( IAdd(4,BNot(IAdd(6,7)) ) ) ) ); 
"
Run Code Online (Sandbox Code Playgroud)

产量:

"[BInt:1]( [BNot:1]( [IAdd:2]( [Dig:4], [BNot:1]( [IAdd:2]( [Dig:6], [Dig:7] ) ) ) ) )"
Run Code Online (Sandbox Code Playgroud)

示例表达式中的宏函数处于非活动状态.当我激活表单时会出现问题 - 各个参数的解析链可以任意长,并且在它们被使用之前它们不会被完全解析.

zwo*_*wol 10

这是通常的习惯用法:

#define mSwitch(Root, Case) mSwitch_(Root, Case)
#define mSwitch_(Root, Case) Root##_Case_##Case
Run Code Online (Sandbox Code Playgroud)

除非#or ##运算符应用于它们,否则在扩展宏本身之前,C预处理器宏的所有参数都会完全展开.然后他们没有扩大.因此,要在之前进行完全扩展##,请通过不使用的包装器宏传递参数##.

  • 不相关的是,出于病态的好奇心,人们在哪里学会写"`函数(论证,论证)`" - 即括号内有空格?我经常看到这种感觉,这让我对美学感到痛苦. (2认同)