gre*_*man 4 c++ macros c-preprocessor
我正在寻找标题中所述问题的一般解决方案.但是,插图考虑我的真实情况.我想得到wstring,像这样:
L"hello"
Run Code Online (Sandbox Code Playgroud)
但是当我有一个宏:
#define MACRO(S) ...
Run Code Online (Sandbox Code Playgroud)
并致电:
MACRO("hello") // no L prefix
Run Code Online (Sandbox Code Playgroud)
如何定义它wstring,像以前一样?
L S
Run Code Online (Sandbox Code Playgroud)
被视为2个符号.
您需要粘贴操作符,查找#和##作为预处理器,以激发新的机会来解决问题并创建有趣的新问题.
http://www.cprogramming.com/reference/preprocessor/token-pasting-operator.html
但是对于您的具体问题,请尝试:
#define MACRO(S) L ## S
Run Code Online (Sandbox Code Playgroud)
根据我的个人经验,粘贴操作符是C++中宏的最佳真正用途之一,因为它为您提供了一些您不能轻易做到的事情.但与大多数预处理器功能一样,它通常用于恶意.
作为一个历史记录,有早期的C编译器,你可以写出#define MACRO(S) L/* */S哪些人做了,因为他们合法地想要标记粘贴,但它没有正式存在.我相信这些日子的评论黑客明显不适用于标准的预处理器.
直接的方法是使用预处理器令牌粘贴(##预处理器运算符),如下所示:
#define MACRO( s ) L ## s
Run Code Online (Sandbox Code Playgroud)
您声明您正在寻找“通用解决方案”,并且基本令牌粘贴不是很通用。
特别是当您想定义一个长字符串时,直接宏变得笨拙
L"Blah blah\n"
L"Second line\n"
L"Third line"
Run Code Online (Sandbox Code Playgroud)
然后,您必须编写例如
MACRO( "Blah blah\n" )
MACRO( "Second line\n" )
MACRO( "Third line" )
Run Code Online (Sandbox Code Playgroud)
令人高兴的是,您可以使用C ++ 11 可变参数宏来支持任意数量的参数,像上面这样编写文字:
MACRO(
"Blah blah\n",
"Second line\n",
"Third line"
)
Run Code Online (Sandbox Code Playgroud)
与MACRO定义为只是,例如
# define WITH_L_PREFIX_( lit ) L##lit
# define MACRO( ... ) MM_APPLY( WITH_L_PREFIX_, __VA_ARGS__ )
Run Code Online (Sandbox Code Playgroud)
然后将问题简化为定义MM_APPLY,例如:
#define MM_APPLY( macroname, ... ) \
MM_INVOKE( \
MM_CONCAT( MM_APPLY_, MM_NARGS( __VA_ARGS__ ) ), \
( macroname, __VA_ARGS__ ) \
)
Run Code Online (Sandbox Code Playgroud)
这反过来又降低了问题定义MM_INVOKE,MM_CONCAT,MM_NARGS,和更具体的MM_APPLY_1通过例如MM_APPLY_21,或任何对参数的数目首选限。这样做的原因主要是为了支持Visual C ++预处理器,它不太符合标准。
关于MM_ARGS产生参数数目的,请参阅Laurent Deniau的原始代码“ VA_NARG ”(2006年1月17日)在Usenet组<comp.std.c>中,例如,存档于(https://groups.google.com /forum/?fromgroups=#!topic/comp.std.c/d-6Mj5Lko_s)。
对于其余的内容,从MM_APPLY_n开始,这些定义看起来像……
#define MM_APPLY_1( macroname, a1 ) \
MM_INVOKE_B( macroname, (a1) )
#define MM_APPLY_2( macroname, a1, a2 ) \
MM_INVOKE_B( macroname, (a1) ) \
MM_APPLY_1( macroname, a2 )
#define MM_APPLY_3( macroname, a1, a2, a3 ) \
MM_INVOKE_B( macroname, (a1) ) \
MM_APPLY_2( macroname, a2, a3 )
Run Code Online (Sandbox Code Playgroud)
再次出于支持特定编译器(这次是g ++)的原因而引入了MM_INVOKE_B。
#define MM_INVOKE( macro, args ) macro args
#define MM_INVOKE_B( macro, args ) macro args // For nested invocation with g++.
Run Code Online (Sandbox Code Playgroud)
MM_CONCAT 很简单
#define MM_CONCAT__( a, b ) a ## b
#define MM_CONCAT_( a, b ) MM_CONCAT__( a, b )
#define MM_CONCAT( a, b ) MM_CONCAT_( a, b )
Run Code Online (Sandbox Code Playgroud)
大概就是这样。
这构成了一些“宏框架”,可以对每个参数进行操作。