如何为宏符号添加前缀?

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个符号.

Ric*_*ett 7

您需要粘贴操作符,查找#和##作为预处理器,以激发新的机会来解决问题并创建有趣的新问题.

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哪些人做了,因为他们合法地想要标记粘贴,但它没有正式存在.我相信这些日子的评论黑客明显不适用于标准的预处理器.


Che*_*Alf 5

基本。

直接的方法是使用预处理器令牌粘贴##预处理器运算符),如下所示:

#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_INVOKEMM_CONCATMM_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)

大概就是这样。

这构成了一些“宏框架”,可以对每个参数进行操作。