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

如何让宏为传入记号赋值并拼接?寻求宏生成器优化方案

问题:如何让宏为传入的记号提供值并展开拼接?

现有解决方案

当前通过定义模板宏+生成器宏的方式实现,但需要单独维护TEMPLATE_*系列宏,与实际使用的拼接模式脱节:

#define TEMPLATE_X_YX_(X, Y, a, b, c) a ## X ## b ## Y ## X ## c
// 其他排列方式的模板宏需单独定义

#define GENERATOR(name, template, ...) \
        const auto name##1 = &TEMPLATE##template(A, 1, __VA_ARGS__); \
        const auto name##2 = &TEMPLATE##template(B, 2, __VA_ARGS__); \
        const auto name##3 = &TEMPLATE##template(C, 3, __VA_ARGS__);

GENERATOR(example, _X_YX_, example_, _mid_, _suffix)

// 预期展开结果:
// const auto example1 = &example_A_mid_1A_suffix;
// const auto example2 = &example_B_mid_2B_suffix;
// const auto example3 = &example_C_mid_3C_suffix;

痛点与期望写法

需要单独定义TEMPLATE_*宏,导致拼接模式与生成逻辑分离,期望直接在生成器中传入拼接模式,写法如下:

GENERATOR(example, example_, X, _mid_, Y, X, _suffix)

解决方案

通过预处理器的递归展开与占位符替换,实现直接传入模式片段的生成器,无需单独定义模板宏:

辅助宏实现

// 强制展开宏参数,解决递归展开延迟问题
#define EXPAND(...) __VA_ARGS__

// 处理单个模式片段:替换X/Y为对应值,其他片段直接保留
#define REPLACE_XY(X_val, Y_val, frag) \
    _REPLACE_XY_##frag(X_val, Y_val)

// X/Y占位符的替换分支
#define _REPLACE_XY_X(X_val, Y_val) X_val
#define _REPLACE_XY_Y(X_val, Y_val) Y_val

// 非X/Y片段的默认处理:直接保留原片段
#define _REPLACE_XY_default(X_val, Y_val, frag) frag
#define _REPLACE_XY_frag(X_val, Y_val) _REPLACE_XY_default(X_val, Y_val, frag)

// 递归遍历所有模式片段,逐个替换后拼接
#define APPLY_PATTERN(X_val, Y_val, ...) \
    _APPLY_PATTERN(X_val, Y_val, __VA_ARGS__)

#define _APPLY_PATTERN(X_val, Y_val, frag, ...) \
    REPLACE_XY(X_val, Y_val, frag) \
    _APPLY_PATTERN_NEXT(X_val, Y_val, __VA_ARGS__)

#define _APPLY_PATTERN_NEXT(X_val, Y_val, ...) \
    EXPAND(_APPLY_PATTERN(X_val, Y_val, __VA_ARGS__))

// 递归终止条件
#define _APPLY_PATTERN(X_val, Y_val)

生成器宏实现

#define GENERATOR(name, ...) \
    const auto name##1 = &APPLY_PATTERN(A, 1, __VA_ARGS__); \
    const auto name##2 = &APPLY_PATTERN(B, 2, __VA_ARGS__); \
    const auto name##3 = &APPLY_PATTERN(C, 3, __VA_ARGS__);

使用示例

GENERATOR(example, example_, X, _mid_, Y, X, _suffix)

展开结果

const auto example1 = &example_A_mid_1A_suffix;
const auto example2 = &example_B_mid_2B_suffix;
const auto example3 = &example_C_mid_3C_suffix;

原理说明

  • REPLACE_XY宏识别模式中的X/Y占位符,替换为传入的实际值(如A/1),非占位符片段直接保留。
  • APPLY_PATTERN通过递归遍历所有模式片段,将替换后的内容拼接成最终的函数名。
  • EXPAND宏强制预处理器多执行一轮展开,确保递归拼接能完全生效。

扩展说明

  • 若需要支持更多占位符(如Z),只需新增对应的_REPLACE_XY_Z宏分支即可。
  • 模式片段可以包含任意合法标识符,只要不与辅助宏的命名(如_REPLACE_XY_开头)冲突即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 19:47:53