1 min to read
Visual Studio 2019 和 C++20 的宏
目錄: C/C++ Macro 宏系列 | CWKSC’s blog | 博客
Visual Studio 2019 的預處理器更新了
C++ 20 的宏也加了一點新東西
以前某些語法真的是 bug
這裏會抄參考MSVC experimental preprocessor overview
和 Announcing full support for a C/C++ conformant preprocessor in MSVC
的内容
▌啟用新的預處理器
右鍵點擊專案 > 屬性 > C/C++ > 命令列
把 /Zc:preprocessor /std:c++latest
放到其他選項
套用 > 確定
▌可變參數宏的逗號省略
傳統的 MSVC 預處理程序會始終在空的 __VA_ARGS__
替換前刪除逗號
新的預處理器更緊密地遵循其他流行的跨平台編譯器的行為
對於要刪除的逗號,可變參數必須丟失(不僅僅是空)
並且必須用 ##
運算符
#define FUNC(a, ...) func(a, ## __VA_ARGS__)
FUNC(1) // 可變參數丟失
-> func(1)
FUNC(1,) // 可變參數沒有丟失,只是空
-> func(1,)
FUNC(1, 2)
-> func(1, 2)
▌宏參數 unpacked【錯誤修復】
傳統的預處理器處理 __VA_ARGS__
時會視為一個整體的 Token 來處理
新的預處理器不會這樣了,會 unpacked 宏參數
傳統的預處理器:
#define get_args0(args0, ...) args0
#define foo(...) get_args0(__VA_ARGS__)
foo(x, y)
get_args0(__VA_ARGS__)
get_args0(x, y) // x, y 被視為一個整體
x, y
新的預處理器:
#define get_args0(args0, ...) args0
#define foo(...) get_args0(__VA_ARGS__)
foo(x, y)
get_args0(__VA_ARGS__)
get_args0(x, y)
x
▌__VA_OPT__(<Token>)
C++ 20 可變參數宏的新功能
它會判斷 ...
有沒有輸入參數
當可變參數丟失(不僅僅是空的)
不會展開括弧裏的 Token
反之而言,沒有丟失則展開
一個示例用法是標準化的逗號分隔
#define M(X, …) X __VA_OPT__(,) __VA_ARGS__
M(3) // expands to 3
M(3,) // expands to 3,
M(3, 4) // expands to 3, 4
注意
#define F(...) f(0 __VA_OPT__(,) __VA_ARGS__)
#define EMP
F(a, b, c) // replaced by f(0, a, b, c)
F() // replaced by f(0)
F(EMP) // replaced by f(0) // 注意