gpt4 book ai didi

c - 带有连接参数的 X-Macro

转载 作者:行者123 更新时间:2023-11-30 15:05:54 24 4
gpt4 key购买 nike

我正在使用 X-Macro 使用以下代码创建枚举

#define WIDGET_OFFSETS                                                               \
X_WIDGET_OFFSET(OFFSET_HEIGHT_WA, 1, OFFSET_HEIGHT_WB, 2, OFFSET_HEIGHT_WC, 3) \
X_WIDGET_OFFSET(OFFSET_WIDTH_WA, 1, OFFSET_WIDTH_WB, 2, OFFSET_WIDTH_WC, 3) \
X_WIDGET_OFFSET(OFFSET_LENGTH_WA, 1, OFFSET_LENGTH_WB, 2, OFFSET_LENGTH_WC, 3)


#define X_WIDGET_OFFSET(a, b, c, d, e, f) a = b,
typedef enum { WIDGET_OFFSETS } Offsets_WA_e;
#undef X_WIDGET_OFFSET

我想更概括地说,X-Macro 表只有四个参数。第一个参数是通用/基本名称,然后将其与附加参数连接起来。我已将宏定义如下,试图完成刚刚显示的代码。

#define WIDGET_OFFSETS                         \
X_WIDGET_OFFSET(OFFSET_HIEGHT_, 1, 2, 3) \
X_WIDGET_OFFSET(OFFSET_WIDTH_, 1, 2, 3) \
X_WIDGET_OFFSET(OFFSET_LENGTH_, 1, 2, 3)

#define EXPAND_NAME(x,y) x##y
#define EXPAND_ENUM_TYPE(z) typedef enum { WIDGET_OFFSETS } Offsets_##z_e;

#define X_WIDGET_OFFSET(a, b, c, d) EXPAND_NAME(a,WA) = b,
EXPAND_ENUM_TYPE(WA)
#undef X_WIDGET_OFFSET

编译器向我提供以下错误消息:

error: expected identifier before ‘(’ token

所以,我的问题似乎出在“EXPAND_NAME(a, WA) = b,”表达式上。我尝试了几种不同的方法,但到目前为止都不起作用。最后也是理想的情况是,我只想指定“WA”、“WB”和“WC”一次,而不是像此处的代码那样指定两次。

我确实发现了类似的问题,Concatenate multiple tokens for X macro ,但如果可能的话,这不完全是我想做的。非常感谢任何对我做错的事情的洞察。谢谢。

编辑:更正了第一个 X-Macro 定义,因为它包含复制/粘贴错误

最佳答案

修复第一个代码块

您的第一个示例代码应该在宏的第三行和第四行中一致地使用 WIDTH 和 LENGTH:

#define WIDGET_OFFSETS                                                               \
X_WIDGET_OFFSET(OFFSET_HEIGHT_WA, 1, OFFSET_HEIGHT_WB, 2, OFFSET_HEIGHT_WC, 3) \
X_WIDGET_OFFSET(OFFSET_WIDTH_WA, 1, OFFSET_WIDTH_WB, 2, OFFSET_WIDTH_WC, 3) \
X_WIDGET_OFFSET(OFFSET_LENGTH_WA, 1, OFFSET_LENGTH_WB, 2, OFFSET_LENGTH_WC, 3)

#define X_WIDGET_OFFSET(a, b, c, d, e, f) a = b,
typedef enum { WIDGET_OFFSETS } Offsets_WA_e;
#undef X_WIDGET_OFFSET
#undef WIDGET_OFFSETS

省略噪音行和重复的空行,结果是:

typedef enum { OFFSET_HEIGHT_WA = 1, OFFSET_WIDTH_WA = 1, OFFSET_LENGTH_WA = 1, } Offsets_WA_e;

修复第二个代码块

您的第二个示例存在问题,特别是它使用 Offsets_ ## z_e 代替了如下所示的 Offsets_ ## z ## _e。通常最好在宏定义的末尾保留分号,并让它们出现在宏调用之后。这是一个指导方针;也有很多异常(exception)。

#define WIDGET_OFFSETS                        \
X_WIDGET_OFFSET(OFFSET_HEIGHT, 1, 2, 3) \
X_WIDGET_OFFSET(OFFSET_WIDTH, 1, 2, 3) \
X_WIDGET_OFFSET(OFFSET_LENGTH, 1, 2, 3)

#define EXPAND_NAME(x,y) x ## _ ## y
#define EXPAND_ENUM_TYPE(z) typedef enum { WIDGET_OFFSETS } Offsets_ ## z ## _e

#define X_WIDGET_OFFSET(a, b, c, d) EXPAND_NAME(a,WA) = b,
EXPAND_ENUM_TYPE(WA);
#undef X_WIDGET_OFFSET

#define X_WIDGET_OFFSET(a, b, c, d) EXPAND_NAME(a,WB) = c,
EXPAND_ENUM_TYPE(WB);
#undef X_WIDGET_OFFSET

#define X_WIDGET_OFFSET(a, b, c, d) EXPAND_NAME(a,WC) = d,
EXPAND_ENUM_TYPE(WC);
#undef X_WIDGET_OFFSET

#undef WIDGET_OFFSETS
#undef EXPAND_ENUM
#undef EXPAND_NAME

产生:

typedef enum { OFFSET_HEIGHT_WA = 1, OFFSET_WIDTH_WA = 1, OFFSET_LENGTH_WA = 1, } Offsets_WA_e;

typedef enum { OFFSET_HEIGHT_WB = 2, OFFSET_WIDTH_WB = 2, OFFSET_LENGTH_WB = 2, } Offsets_WB_e;

typedef enum { OFFSET_HEIGHT_WC = 3, OFFSET_WIDTH_WC = 3, OFFSET_LENGTH_WC = 3, } Offsets_WC_e;

避免重复后缀

您担心的是后缀 WA、WB 和 WC 在代码中重复,而您不想这样重复。可以解决这个问题。一种方法是将参数传递给 WIDGET_OFFSETS 宏,如下所示:

#define WIDGET_OFFSETS(sx)                    \
X_WIDGET_OFFSET(EXPAND_NAME(OFFSET_HEIGHT, sx), 1, 2, 3) \
X_WIDGET_OFFSET(EXPAND_NAME(OFFSET_WIDTH, sx), 1, 2, 3) \
X_WIDGET_OFFSET(EXPAND_NAME(OFFSET_LENGTH, sx), 1, 2, 3)

#define EXPAND_NAME(x,y) x ## _ ## y
#define EXPAND_ENUM_TYPE(z) typedef enum { WIDGET_OFFSETS(z) } Offsets_ ## z ## _e

#define X_WIDGET_OFFSET(a, b, c, d) a = b,
EXPAND_ENUM_TYPE(WA);
#undef X_WIDGET_OFFSET

#define X_WIDGET_OFFSET(a, b, c, d) a = c,
EXPAND_ENUM_TYPE(WB);
#undef X_WIDGET_OFFSET

#define X_WIDGET_OFFSET(a, b, c, d) a = d,
EXPAND_ENUM_TYPE(WC);
#undef X_WIDGET_OFFSET

#undef WIDGET_OFFSETS
#undef EXPAND_ENUM
#undef EXPAND_NAME

这会产生以下结果,与之前相同,但 WA、WB 和 WC 在源中仅出现一次。

typedef enum { OFFSET_HEIGHT_WA = 1, OFFSET_WIDTH_WA = 1, OFFSET_LENGTH_WA = 1, } Offsets_WA_e;

typedef enum { OFFSET_HEIGHT_WB = 2, OFFSET_WIDTH_WB = 2, OFFSET_LENGTH_WB = 2, } Offsets_WB_e;

typedef enum { OFFSET_HEIGHT_WC = 3, OFFSET_WIDTH_WC = 3, OFFSET_LENGTH_WC = 3, } Offsets_WC_e;

关于c - 带有连接参数的 X-Macro,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39482271/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com