下面是我升级到编译器的新版本时,碰到了一个疑难杂症:
不必要使用标记粘贴运算符(##
)是不可移植的,可能产生不希望的空白,警告或错误。
当令牌粘贴操作符的结果不是有效的预处理令牌时,令牌粘贴操作符是不必要的,并且可能有害。
例如,一个可以尝试使用该令牌粘贴操作在编译时建立字符串文字:
#define STRINGIFY(x) #x
#define PLUS(a, b) STRINGIFY(a##+##b)
#define NS(a, b) STRINGIFY(a##::##b)
printf("%s %s\n", PLUS(1,2), NS(std,vector));
在一些编译器,这将输出预期的结果:
1+2 std::vector
在其他编译器,这将包括不需要的空白:
1 + 2 std :: vector
相当现代的版本GCC的附加组件(> = 3.3左右)将无法被编译的代码:
foo.cpp:16:1: pasting "1" and "+" does not give a valid preprocessing token
foo.cpp:16:1: pasting "+" and "2" does not give a valid preprocessing token
foo.cpp:16:1: pasting "std" and "::" does not give a valid preprocessing token
foo.cpp:16:1: pasting "::" and "vector" does not give a valid preprocessing token
的解决方案是串联预处理器令牌C/C++运营商时,可以省略令牌粘贴操作者:
#define STRINGIFY(x) #x
#define PLUS(a, b) STRINGIFY(a+b)
#define NS(a, b) STRINGIFY(a::b)
printf("%s %s\n", PLUS(1,2), NS(std,vector));
GCC CPP documentation chapter on concatenation在令牌粘贴操作符上有更多有用的信息。
既然你可以连接在编译时字符串文字,你可以在创建日期表达减少'的std :: wstring的创建日期=扩大( __DATE__)L“”WIDEN(__ TIME __);`并立即隐式构建整个字符串。 – user666412 2016-02-15 17:54:19