如何在C++14中用X宏生成无if(0)的链式else if?
在C++14中用X宏生成无冗余if(0)的else if链
当然可以做到。核心思路是通过预处理宏技巧拆分X宏列表的第一个元素和剩余元素,让第一个元素生成独立的if分支,剩余元素逐个展开为else if,彻底避免无意义的if(0)起始项。
具体实现示例
假设外部模块提供的X宏列表定义如下:
// 外部模块提供的字符串匹配列表:X(字符串, 处理函数) #define STRING_MATCH_LIST \ X("apple", process_apple) \ X("banana", process_banana) \ X("cherry", process_cherry)
我们可以编写以下辅助宏来生成干净的else if链:
// 定义分支生成宏:第一个分支用if,后续用else if #define X_FIRST(str, func) if (strcmp(input, str) == 0) { func(); } #define X_REST(str, func) else if (strcmp(input, str) == 0) { func(); } // 提取第一个列表项并展开为if #define GET_FIRST_CASE(...) GET_FIRST_HELPER(__VA_ARGS__, dummy) #define GET_FIRST_HELPER(X1, ...) X_FIRST X1 // 提取剩余列表项并展开为else if链 // 兼容C++14的参数计数与循环宏 #define COUNT_ARGS(...) COUNT_ARGS_HELPER(__VA_ARGS__, 3, 2, 1, 0) #define COUNT_ARGS_HELPER(_1, _2, _3, N, ...) N #define VA_FOR_EACH_0(macro) #define VA_FOR_EACH_1(macro, a) macro a #define VA_FOR_EACH_2(macro, a, b) macro a VA_FOR_EACH_1(macro, b) #define VA_FOR_EACH_3(macro, a, b, c) macro a VA_FOR_EACH_2(macro, b, c) #define VA_FOR_EACH_N(macro, N, ...) VA_FOR_EACH_##N(macro, __VA_ARGS__) #define VA_FOR_EACH(macro, ...) VA_FOR_EACH_N(macro, COUNT_ARGS(__VA_ARGS__), __VA_ARGS__) #define GET_REST_CASES(...) GET_REST_HELPER(__VA_ARGS__, dummy) #define GET_REST_HELPER(X1, ...) VA_FOR_EACH(X_REST, __VA_ARGS__) // 最终展开宏 #define EXPAND_MATCH_CHAIN() \ GET_FIRST_CASE(STRING_MATCH_LIST) \ GET_REST_CASES(STRING_MATCH_LIST)
使用方式
在函数中调用展开宏即可生成干净的分支链,还能按需添加默认分支:
void match_string(const char* input) { EXPAND_MATCH_CHAIN(); // 默认处理分支 else { process_default(); } }
展开效果
预处理后会生成完全符合预期的代码:
void match_string(const char* input) { if (strcmp(input, "apple") == 0) { process_apple(); } else if (strcmp(input, "banana") == 0) { process_banana(); } else if (strcmp(input, "cherry") == 0) { process_cherry(); } else { process_default(); } }
这种方式完全规避了哈希冲突的风险,同时保持了X宏同步外部列表的便利性,在C++14环境下可以稳定运行。
内容的提问来源于stack exchange,提问作者Questor
相关产品推荐
相关产品推荐

