如何实现支持多变量打印的C++可变参数DUMP调试宏
实现方案
我们提供两种实现,分别适配不同C++版本的编译环境:
方案1:C++20 极简实现
基于C++20的折叠表达式实现,代码简洁无依赖,无需额外宏工具:
#include <iostream> #define DUMP(...) \ do { \ std::cerr << __FILE__ << ":" << __LINE__ << ": "; \ bool first_param = true; \ ([&](auto&& val) { \ if (!first_param) std::cerr << ", "; \ first_param = false; \ std::cerr << #val << "=\"" << val << "\""; \ }(__VA_ARGS__), ...); \ std::cerr << '\n'; \ } while(0)
方案2:兼容C++11及以上版本的实现
如果你的编译环境不支持C++20,可以用递归宏展开可变参数,默认最多支持10个参数(可按需扩展):
#include <iostream> // 通用工具宏:将指定宏应用到所有可变参数上 #define MAP(F, ...) MAP_IMPL(F, __VA_ARGS__) #define MAP_IMPL(F, ...) \ GET_MACRO(__VA_ARGS__, MAP_10, MAP_9, MAP_8, MAP_7, MAP_6, MAP_5, MAP_4, MAP_3, MAP_2, MAP_1)(F, __VA_ARGS__) #define GET_MACRO(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,NAME,...) NAME #define MAP_1(F,x) F(x) #define MAP_2(F,x,...) F(x) MAP_1(F,__VA_ARGS__) #define MAP_3(F,x,...) F(x) MAP_2(F,__VA_ARGS__) #define MAP_4(F,x,...) F(x) MAP_3(F,__VA_ARGS__) #define MAP_5(F,x,...) F(x) MAP_4(F,__VA_ARGS__) #define MAP_6(F,x,...) F(x) MAP_5(F,__VA_ARGS__) #define MAP_7(F,x,...) F(x) MAP_6(F,__VA_ARGS__) #define MAP_8(F,x,...) F(x) MAP_7(F,__VA_ARGS__) #define MAP_9(F,x,...) F(x) MAP_8(F,__VA_ARGS__) #define MAP_10(F,x,...) F(x) MAP_9(F,__VA_ARGS__) // DUMP宏实现 #define DUMP_FIRST(arg) #arg << "=\"" << (arg) << "\"" #define DUMP_REST(arg) << ", " << #arg << "=\"" << (arg) << "\"" #define DUMP(first, ...) \ do { \ std::cerr << __FILE__ << ":" << __LINE__ << ": " \ << DUMP_FIRST(first) \ MAP(DUMP_REST, __VA_ARGS__) \ << std::endl; \ } while(0)
使用示例
int main() { int foo = 42; std::string bar = "barval"; const char* baz = "baz's val"; DUMP(foo, bar, baz); // 输出示例:my_file.cpp:10: foo="42", bar="barval", baz="baz's val" return 0; }
注意事项
- 所有变量都用括号包裹,避免表达式优先级导致的输出错误
- 用
do{}while(0)包裹是宏的标准写法,避免宏在if、for等分支语句中展开时出现语法错误 - 兼容C++11的方案默认最多支持10个参数,如需更多参数可按规则扩展
MAP_11、MAP_12等宏即可
内容的提问来源于stack exchange,提问作者mpen
相关产品推荐
相关产品推荐

