You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让支持多参数的EXPAND_FUNC宏兼容空参数场景?

问题:让EXPAND_FUNC宏支持空参数场景

我需要一个可根据参数生成函数的宏,例如调用EXPAND_FUNC(func, int)时,生成如下函数:

void func(int a)
{
    _func(a);
}

现有实现代码如下:

#define CONCAT_(a, b) a##b
#define CONCAT(a, b) CONCAT_(a, b)

#define EXPAND(x) x
#define ARG_N(...) EXPAND(NARG(__VA_ARGS__, RSEQN()))
#define NARG(...) EXPAND(ARG_N_(__VA_ARGS__))

#define ARG_N_(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
#define RSEQN() 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
#define GET_MACRO(func, ...) CONCAT(func, EXPAND(ARG_N(__VA_ARGS__)))
#define COMPOSE(name, ...) EXPAND(name(__VA_ARGS__))

#define PARAMS(...) COMPOSE(GET_MACRO(PARAMS_, __VA_ARGS__), __VA_ARGS__)

#define PARAMS_0()
#define PARAMS_1(A) A a
#define PARAMS_2(A, B) A a, B b
#define PARAMS_3(A, B, C) A a, B b, C c
#define PARAMS_4(A, B, C, D) A a, B b, C c, D d
#define PARAMS_5(A, B, C, D, E) A a, B b, C c, D d, E e
#define PARAMS_6(A, B, C, D, E, F) A a, B b, C c, D d, E e, F f

#define ARGS(...) COMPOSE(GET_MACRO(ARGS_, __VA_ARGS__), __VA_ARGS__)

#define ARGS_0()
#define ARGS_1(A) a
#define ARGS_2(A, B) a, b
#define ARGS_3(A, B, C) a, b, c
#define ARGS_4(A, B, C, D) a, b, c, d
#define ARGS_5(A, B, C, D, E) a, b, c, d, e
#define ARGS_6(A, B, C, D, E, F) a, b, c, d, e, f

#define EXPAND_FUNC(name, ...) \
    void name(PARAMS(__VA_ARGS__)) \
    { \
        _##name(ARGS(__VA_ARGS__));\
    }

当前EXPAND_FUNC宏支持一个或多个参数,但无法处理空参数场景。调用EXPAND_FUNC(func0)时,会错误展开为:

void func0(a)
{
    _func0(a);
}

请问如何修改才能让EXPAND_FUNC(func0)正常工作?


解决方案

问题根源

当__VA_ARGS__为空时,原有参数计数宏会错误地将其识别为1个空参数,导致调用PARAMS_1()和ARGS_1(),最终展开出无效的a标识符。

修改方案

新增空参数判断逻辑,让计数宏在__VA_ARGS__为空时返回0,从而正确调用PARAMS_0()和ARGS_0()。

修改后的完整代码

#define CONCAT_(a, b) a##b
#define CONCAT(a, b) CONCAT_(a, b)

#define EXPAND(x) x

// 判断可变参数是否为空
#define HAS_ARGS(...) EXPAND(HAS_ARGS_(__VA_ARGS__, 1, 0))
#define HAS_ARGS_(_1, _2, ...) _2

// 条件选择辅助宏
#define IF(cond, then, else) CONCAT(IF_, cond)(then, else)
#define IF_1(then, else) then
#define IF_0(then, else) else

// 修正参数计数:空参数返回0,非空返回实际参数个数
#define ARG_N(...) \
    EXPAND(IF(HAS_ARGS(__VA_ARGS__), NARG(__VA_ARGS__, RSEQN()), 0))

#define NARG(...) EXPAND(ARG_N_(__VA_ARGS__))
#define ARG_N_(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
#define RSEQN() 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0

#define GET_MACRO(func, ...) CONCAT(func, EXPAND(ARG_N(__VA_ARGS__)))
#define COMPOSE(name, ...) EXPAND(name(__VA_ARGS__))

#define PARAMS(...) COMPOSE(GET_MACRO(PARAMS_, __VA_ARGS__), __VA_ARGS__)

#define PARAMS_0()
#define PARAMS_1(A) A a
#define PARAMS_2(A, B) A a, B b
#define PARAMS_3(A, B, C) A a, B b, C c
#define PARAMS_4(A, B, C, D) A a, B b, C c, D d
#define PARAMS_5(A, B, C, D, E) A a, B b, C c, D d, E e
#define PARAMS_6(A, B, C, D, E, F) A a, B b, C c, D d, E e, F f

#define ARGS(...) COMPOSE(GET_MACRO(ARGS_, __VA_ARGS__), __VA_ARGS__)

#define ARGS_0()
#define ARGS_1(A) a
#define ARGS_2(A, B) a, b
#define ARGS_3(A, B, C) a, b, c
#define ARGS_4(A, B, C, D) a, b, c, d
#define ARGS_5(A, B, C, D, E) a, b, c, d, e
#define ARGS_6(A, B, C, D, E, F) a, b, c, d, e, f

#define EXPAND_FUNC(name, ...) \
    void name(PARAMS(__VA_ARGS__)) \
    { \
        _##name(ARGS(__VA_ARGS__));\
    }

效果验证

  • 调用EXPAND_FUNC(func0)时,生成正确的无参函数:
    void func0()
    {
        _func0();
    }
    
  • 调用EXPAND_FUNC(func, int)时,依然正常生成单参数函数:
    void func(int a)
    {
        _func(a);
    }
    

内容的提问来源于stack exchange,提问作者user28234794

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 16:41:00