下面是我升級到編譯器的新版本時,碰到了一個疑難雜症:
不必要使用標記粘貼運算符(##
)是不可移植的,可能產生不希望的空白,警告或錯誤。
當令牌粘貼操作符的結果不是有效的預處理令牌時,令牌粘貼操作符是不必要的,並且可能有害。
例如,一個可以嘗試使用該令牌粘貼操作在編譯時建立字符串文字:
#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