能否用C++可变参数宏实现提取仅偶数位置参数的ONLY_EVEN宏?
实现ONLY_EVEN可变参数宏提取偶数位置参数
要实现一个可变参数宏ONLY_EVEN(),提取参数列表中偶数位置(从1开始计数)的参数,满足以下规则:
ONLY_EVEN()无输出ONLY_EVEN(a,b)输出bONLY_EVEN(a,b,c,d)输出b,d- 支持任意数量的参数(可按需扩展最大支持个数)
实现思路
利用C99可变参数宏特性,结合递归宏展开和参数计数技巧:
- 用递归宏每次提取当前参数对的第二个元素(偶数位置)
- 通过参数计数判断剩余参数是否足够组成新的参数对,避免多余逗号
- 定义终止宏处理参数为空或仅剩单个参数的情况
代码实现
// 参数计数宏:最多支持10个参数,可按需扩展 #define _COUNT_ARGS(...) \ _COUNT_ARGS_HELPER(__VA_ARGS__, 10,9,8,7,6,5,4,3,2,1,0) #define _COUNT_ARGS_HELPER(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,n,...) n // 根据剩余参数个数决定是否添加逗号 #define _COMMA_IF_HAS_TWO(...) \ _COMMA_IF_HAS_TWO_HELPER(_COUNT_ARGS(__VA_ARGS__), __VA_ARGS__) #define _COMMA_IF_HAS_TWO_HELPER(n, ...) \ _COMMA_IF_HAS_TWO_##n(__VA_ARGS__) #define _COMMA_IF_HAS_TWO_0(...) #define _COMMA_IF_HAS_TWO_1(...) #define _COMMA_IF_HAS_TWO_2(...) , #define _COMMA_IF_HAS_TWO_3(...) , #define _COMMA_IF_HAS_TWO_4(...) , #define _COMMA_IF_HAS_TWO_5(...) , #define _COMMA_IF_HAS_TWO_6(...) , #define _COMMA_IF_HAS_TWO_7(...) , #define _COMMA_IF_HAS_TWO_8(...) , #define _COMMA_IF_HAS_TWO_9(...) , #define _COMMA_IF_HAS_TWO_10(...) , // 核心递归宏:处理参数对,提取偶数位置元素 #define ONLY_EVEN_IMPL() #define ONLY_EVEN_IMPL(one) #define ONLY_EVEN_IMPL(first, second, ...) \ second _COMMA_IF_HAS_TWO(__VA_ARGS__) ONLY_EVEN_IMPL(__VA_ARGS__) // 对外暴露的宏入口 #define ONLY_EVEN(...) ONLY_EVEN_IMPL(__VA_ARGS__)
测试用例
#include <stdio.h> int main() { // 无参数:无输出 printf("ONLY_EVEN(): %s\n", #ONLY_EVEN()); // 2个参数:输出b printf("ONLY_EVEN(a,b): %s\n", #ONLY_EVEN(a,b)); // 4个参数:输出b,d printf("ONLY_EVEN(a,b,c,d): %s\n", #ONLY_EVEN(a,b,c,d)); // 3个参数:输出b printf("ONLY_EVEN(a,b,c): %s\n", #ONLY_EVEN(a,b,c)); // 6个参数:输出b,d,f printf("ONLY_EVEN(a,b,c,d,e,f): %s\n", #ONLY_EVEN(a,b,c,d,e,f)); return 0; }
输出结果
ONLY_EVEN(): ONLY_EVEN(a,b): b ONLY_EVEN(a,b,c,d): b,d ONLY_EVEN(a,b,c): b ONLY_EVEN(a,b,c,d,e,f): b,d,f
扩展说明
如果需要支持超过10个参数,只需:
- 扩展
_COUNT_ARGS_HELPER的参数列表(比如增加到20个) - 对应添加
_COMMA_IF_HAS_TWO_11到_COMMA_IF_HAS_TWO_20的宏定义(内容均为,)
内容的提问来源于stack exchange,提问作者xrrjchvizeçq
相关产品推荐
相关产品推荐

