标签: variadic-macros

如何在嵌套上下文中通过 __VA_OPT__ 扩展递归宏

我读过这篇文章,它说明了如何__VA_OPT__使用函数宏来递归扩展宏。我想实现类似的东西,不同之处在于宏是在嵌套上下文中扩展的。

输入:

NEST_RECURSIVE(A, B, C)
Run Code Online (Sandbox Code Playgroud)

应该产生(顺序无关):

((( | C) | B) | A)
Run Code Online (Sandbox Code Playgroud)

我的方法稍微概括了这篇文章:

#define PARENS ()

#define EXPAND(...) EXPAND4(EXPAND4(EXPAND4(EXPAND4(__VA_ARGS__))))
#define EXPAND4(...) EXPAND3(EXPAND3(EXPAND3(EXPAND3(__VA_ARGS__))))
#define EXPAND3(...) EXPAND2(EXPAND2(EXPAND2(EXPAND2(__VA_ARGS__))))
#define EXPAND2(...) EXPAND1(EXPAND1(EXPAND1(EXPAND1(__VA_ARGS__))))
#define EXPAND1(...) __VA_ARGS__

#define FOR_EACH_R(func, ...) __VA_OPT__(EXPAND(FOR_EACH_HELPER_R(func, __VA_ARGS__)))
#define FOR_EACH_HELPER_R(func, sub, ...) func(__VA_OPT__(FOR_EACH_AGAIN_R PARENS (func, __VA_ARGS__)), sub)
#define FOR_EACH_AGAIN_R() FOR_EACH_HELPER_R

#define MY_FUNC(nested, var) (nested | var)
#define NEST_RECURSIVE(...) FOR_EACH_R(MY_FUNC, __VA_ARGS__)
Run Code Online (Sandbox Code Playgroud)

当前代码产生以下输出:

(FOR_EACH_HELPER_R (MY_FUNC, B, C) | A)
Run Code Online (Sandbox Code Playgroud)

可以看出,扩展不会发生在第一级之后。

我想我必须EXPAND别的地方,但是,我不知道在哪里。

我想要做的事情完全有可能是不可能的,但是,C++20 之前的递归宏扩展方法(利用PP_NARG)确实适用于嵌套,所以我希望新的、更干净的方法可以使用它还有!

c++ macros c-preprocessor variadic-macros c++20

1
推荐指数
1
解决办法
670
查看次数

如何在 Rust 中编写宏来匹配集合中的任何元素?

在 C 语言中,我习惯于:

if (ELEM(value, a, b, c)) { ... }
Run Code Online (Sandbox Code Playgroud)

这是一个具有可变数量参数的宏,以避免输入

if (value == a || value == b || value == c) { ... }
Run Code Online (Sandbox Code Playgroud)

C 示例可以在与 C 一起使用的 Varargs `ELEM` 宏中看到。

这在 Rust 中可能吗?我认为它会使用match. 如果是这样,如何使用可变参数来实现这一目标?

macros rust variadic-macros

0
推荐指数
1
解决办法
769
查看次数

variadic macro - 可选的初始化表达式

我想要一个macro声明int一个给定名称和可选的初始化表达式.

我尝试在Stack Overflow上使用这个答案,但没有成功.

这是我试过的:

#define macro(...) int FIRST(__VA_ARGS__)(REST(__VA_ARGS__))
Run Code Online (Sandbox Code Playgroud)

这样使用时没有问题:

macro(foo);
Run Code Online (Sandbox Code Playgroud)

但是当给出初始化器时会出现错误:

macro(foo, 42);
Run Code Online (Sandbox Code Playgroud)

另一种 - 只是使用时会在没有参数的情况下__VA_ARGS__-pedanticGCC 发出警告.

我怎样才能解决这个问题?

()当没有初始化表达式时,是否也可以避免括号 - 这意味着没有零初始化但是默认?

请注意,我的真实用例不仅适用int于任何类型,而且使用像boost这样的第三方也不是一种选择.

c++ c-preprocessor variadic-macros c++11

0
推荐指数
1
解决办法
131
查看次数

为什么可变参数宏如此令人不快?

与例如 C++ 的可变参数模板相比,CPP(C/C++ 预处理器;为简单起见,我将在本问题中将其视为一种单独的语言)中的可变参数宏非常有限。本质上,可变参数宏只是带有参数的宏,其参数允许包含逗号。这没有提供计算参数、一个接一个操作参数等的直接方法。这些事情是可能的,但需要精心设计、令人困惑且编译缓慢的技巧,例如本问题中描述的技巧。唯一可以直接处理的事情VA_ARGS就是将它们传递给可变参数函数。

我的问题是,他们为什么要这样设计?在像 CPP 这样的任何纯函数式语言中,列表的标准方法是 cons 样式的模式匹配:处理列表的第一个参数并递归其余部分,并为空列表设置基本情况。标准委员会成员应该非常熟悉这种方法。

为什么 CPP 的可变参数宏没有采用这样的方法?可变参数宏是否只是一种包装可变参数函数的方法,这样就不需要对参数列表进行操作?是否存在一些潜在的问题使得允许可变参数宏递归变得不切实际?或者...?

注意:我不是在寻找“因为人们不应该想要可变参数宏”形式的答案/评论。boost.preprocessor 之类的东西的存在表明,理性的人希望以非平凡的方式使用预处理器。也不寻求关于为什么其他设计是一个好/坏主意的个人意见。我试图找出当时的实际推理。

c c++ language-lawyer c-preprocessor variadic-macros

-2
推荐指数
1
解决办法
400
查看次数

变体宏不起作用

我想要做的是使用宏访问代码.但编译器给了我这个错误

标识符"BUTTON___button"未定义

#define BUTTON_1                HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_8)
#define BUTTON_2                HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_9)
#define BUTTON_3                HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_4)
#define BUTTON_4                HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_5)
#define BUTTON_5                HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13)
#define BUTTON_6                HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_14)
#define BUTTON_7                HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_12)
#define BUTTON_8                HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_11)
#define BUTTON_9                HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_15)
#define BUTTON_10               HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_0)
#define BUTTON_11               HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_10)
#define BUTTON_12               HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_15)
#define BUTTON_13               HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1)
#define BUTTON_14               HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_2)
#define BUTTON_15               HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_11)
#define BUTTON_16               HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2)
#define BUTTON_17               HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_0)
#define BUTTON_18               HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_1)
#define BUTTON_19               HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_5)
#define BUTTON_20 …
Run Code Online (Sandbox Code Playgroud)

c macros variadic-macros

-3
推荐指数
1
解决办法
81
查看次数