我有一个普通的宏:
#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
如何保证变量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]
这是调试代码,递归解析嵌套表达式没有问题,如:
DebugInfo( BInt( BNot( IAdd(4,BNot(IAdd(6,7)) ) ) ) );
"
产生:
"[BInt:1]( [BNot:1]( [IAdd:2]( [Dig:4], [BNot:1]( [IAdd:2]( [Dig:6], [Dig:7] ) ) ) ) )"
示例表达式中的宏函数处于非活动状态。当我激活表单时会出现问题 - 各个参数的解析链可以任意长,并且在它们被使用之前它们不会被完全解析。
答案 0 :(得分:8)
这是通常的习惯用语:
#define mSwitch(Root, Case) mSwitch_(Root, Case)
#define mSwitch_(Root, Case) Root##_Case_##Case
在扩展宏本身之前,C预处理器宏的所有参数都已完全展开,除非 #
或##
运算符应用于它们;然后他们没有扩大。因此,要在##
之前进行完全展开,请通过不使用##
的包装器宏传递参数。