我正在寻找标题中所述问题的一般解决方案。但是,插图考虑我的真实情况。我想得到wstring
,就像这样:
L"hello"
但是当我有一个宏时:
#define MACRO(S) ...
和电话:
MACRO("hello") // no L prefix
如何像以前一样定义它来获取wstring
?
L S
被视为2个符号。
答案 0 :(得分:5)
您需要粘贴操作符,查找#和##作为预处理器,以激发新的机会来解决问题并创建有趣的新问题。
http://www.cprogramming.com/reference/preprocessor/token-pasting-operator.html
但是针对您的具体问题,请尝试:
#define MACRO(S) L ## S
根据我的个人经验,粘贴操作符是C ++中最好的宏用途之一,因为它为您提供了一些在没有它的情况下无法轻松完成的操作。但与大多数预处理器功能一样,它通常用于恶意。
作为一个历史记录,有早期的C编译器,你可以写#define MACRO(S) L/* */S
人们做的,因为他们合法地想要标记粘贴,但它没有正式存在。我相信这些日子的评论黑客明显不适用于标准的预处理器。
答案 1 :(得分:4)
直接的方法是使用预处理器令牌粘贴,##
预处理器运算符,如下所示:
#define MACRO( s ) L ## s
你说你正在寻找一个“通用解决方案”,并且基本的令牌粘贴不是很笼统。
特别是当您想要定义像
这样的长字符串时,简单的宏会变得很笨拙L"Blah blah\n"
L"Second line\n"
L"Third line"
然后你必须写下例如。
MACRO( "Blah blah\n" )
MACRO( "Second line\n" )
MACRO( "Third line" )
很高兴您可以使用C ++ 11 可变参数宏来支持任意数量的参数,编写上面的文字如下:
MACRO(
"Blah blah\n",
"Second line\n",
"Third line"
)
将MACRO
定义为,例如,
# define WITH_L_PREFIX_( lit ) L##lit
# define MACRO( ... ) MM_APPLY( WITH_L_PREFIX_, __VA_ARGS__ )
然后问题被简化为定义MM_APPLY
,例如像这样:
#define MM_APPLY( macroname, ... ) \
MM_INVOKE( \
MM_CONCAT( MM_APPLY_, MM_NARGS( __VA_ARGS__ ) ), \
( macroname, __VA_ARGS__ ) \
)
反过来又减少了定义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&gt ;例如存档于(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 )
,再次出于支持特定编译器的原因(这次是g ++)引入了MM_INVOKE_B
。
#define MM_INVOKE( macro, args ) macro args
#define MM_INVOKE_B( macro, args ) macro args // For nested invocation with g++.
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 )
就是这样,粗略。
这构成了一个小的“宏框架”,将操作应用于每个参数。