在宏定义中连接两个字符串(Clang)

时间:2012-09-17 13:12:49

标签: c++ xcode4 macros clang

我正在研究一些最初在MSVC中制作的代码,我正试图让它在Clang上编译(使用Xcode)。我得到的代码是这样的:

#define DO_MAPPING(x,y,z)\
    myMaps[map##x] = GetTex( #x##"Map" );\
    myRemaps[map##x] = GetHandle( #x##"Remap" );

目前我收到一个构建错误,说粘贴形成了字符串"Height""Map",我真正想要"HeightMap"。这段代码适用于MSVC,Clang的宏语法有什么意义,这意味着这种东西需要以不同的方式编写吗?

4 个答案:

答案 0 :(得分:3)

在C中,"X""Y"相当于"XY"。但是,当你在宏中写这样的东西时:

str1##str2

你告诉词法分析者将两者作为一个标记连接起来。 "X""Y"实际上是由lexer 1 连接的两个标记,而"X"##"Y"应该是一个标记(它不是有效的标记)。

您需要的是简单地删除##

#define DO_MAPPING(x,y,z)\
    myMaps[map##x] = GetTex( #x "Map" );\
    myRemaps[map##x] = GetHandle( #x "Remap" );

1 或语义分析器,具体取决于实现


通常,匹配字符串的正则表达式如下所示(简化):

"(a|\b)*"

(假设a是所有不需要转义的字符列表,b是其他字符。也许,对于MSVC,它的定义如下:

"(a|\b)*"s*+

s是空格)

这意味着MSVC可能会将"X" "Y"视为一个令牌,而不是两个。

答案 1 :(得分:2)

只需使用(#x "Map")代替#x##"Map"。它应该在C ++中工作。例如。这完全有效:("B" "Map")并评估为"BMap"

答案 2 :(得分:1)

请注意,"Height""Map"在解析时实际上与"HeightMap"相同。所以你可以简单地使用它:

#define DO_MAPPING(x,y,z)\
    myMaps[map##x] = GetTex( #x "Map" );\
    myRemaps[map##x] = GetHandle( #x "Remap" );

答案 3 :(得分:1)

请改为尝试:

#define DO_MAPPING(x,y,z)\
    myMaps[map##x] = GetTex( #x "Map" );\
    myRemaps[map##x] = GetHandle( #x "Remap" );

编译器会自动连接两个字符串文字。