如何定义宏以从单个值生成两个参数?附现有代码示例
简化ToolTipMap插入操作的宏实现方案
嘿,我明白你现在的需求——每次往ToolTipMap里插入ToolTipPair都要重复写类型名和一对对应ID,确实有点繁琐。结合你给出的代码场景,我来给你几个实用的宏方案,帮你减少重复代码:
方案一:利用ID命名规则自动生成配对ID
从你的代码能看出来,控件ID(IDC_xxx)和对应的字符串ID(IDS_xxx)后缀完全一致,这种情况下可以用预处理器的**连接运算符##**来自动拼接前缀和后缀,只需要传一次后缀就能生成完整的两个ID:
宏定义
// 定义宏:接收map对象和ID后缀,自动插入对应的ToolTipPair #define INSERT_TOOLTIP(map, id_suffix) \ map.insert(ToolTipPair(IDC_##id_suffix, IDS_##id_suffix))
使用方式
这样你原来的插入代码就可以简化成:
ToolTipMap mapToolTips; INSERT_TOOLTIP(mapToolTips, COMBO_WATCHTOWER_DAY); INSERT_TOOLTIP(mapToolTips, COMBO_SCHOOL_DAY); INSERT_TOOLTIP(mapToolTips, EDIT_DATE_FORMAT); INSERT_TOOLTIP(mapToolTips, CHECK_USE_CUSTOM_DATE); // 后续的插入操作都可以用这个宏完成
原理说明
##是C++预处理器的连接运算符,它会把左边的IDC_和传入的id_suffix(比如COMBO_WATCHTOWER_DAY)拼接成完整的标识符IDC_COMBO_WATCHTOWER_DAY,同理处理IDS_前缀。- 这个宏的前提是你的控件ID和字符串ID必须严格遵循
IDC_xxx和IDS_xxx的命名规则,后缀完全一致才能正常工作。
方案二:通用型宏(不依赖命名规则)
如果后续你的ID命名规则可能变化,或者有个别配对不遵循后缀一致的规则,可以用更通用的宏,直接传入两个ID,省去重复写ToolTipPair的麻烦:
宏定义
// 定义通用宏:接收map对象、控件ID和字符串ID,插入对应的pair #define INSERT_TOOLTIP_PAIR(map, ctrl_id, str_id) \ map.insert(ToolTipPair(ctrl_id, str_id))
使用方式
ToolTipMap mapToolTips; INSERT_TOOLTIP_PAIR(mapToolTips, IDC_COMBO_WATCHTOWER_DAY, IDS_COMBO_WATCHTOWER_DAY); INSERT_TOOLTIP_PAIR(mapToolTips, IDC_CHECK_USE_CUSTOM_DATE, IDS_CHECK_USE_CUSTOM_DATE);
额外注意事项
- 宏在预处理阶段会直接展开,所以调试时如果遇到问题,可以查看预编译后的代码确认宏展开是否正确。
- 如果你的
map是复杂表达式(比如指针访问pMap->),记得在宏里给map加括号,避免优先级问题,比如:#define INSERT_TOOLTIP(map, id_suffix) \ (map)->insert(ToolTipPair(IDC_##id_suffix, IDS_##id_suffix))
内容的提问来源于stack exchange,提问作者Andrew Truckle




