C预处理器:从__VA_ARGS__中提取[0...N]个参数

4

如何从VA_ARGS中提取[0...N]个参数,假设N小于等于参数数量。

示例:

#define MY_SEQ r0, r1, r2,  r3,  r4,  r5,  r6,  r7, \
               r8, r9, r10, r11, r12, r13, r14, r15

#define EXTRACT_N(n, SEQ) {... magic ...}

...

EXTRACT_N(5, (MY_SEQ()));

should expand to:

{r0, r1, r2, r3, r4};

可以假设序列元素的形式为WHATEVER##N,其中N是第N个元素。

我正在寻找一些好的解决方案来解决这个问题,而不使用BOOST,例如,我想了解如何完成它。

我使用迭代方法完成了它,但我想知道是否有其他方法可以完成它。 以下是我的实现方式:

#define EXTRACT_1(t0)               t0
#define EXTRACT_2(t0, t1)           EXTRACT_1(t0),t1
#define EXTRACT_3(t0, t1, t2)       EXTRACT_2(t0, t1),t2
#define EXTRACT_4(t0, t1, t2, t3)   EXTRACT_3(t0, t1, t2),t3
...
1个回答

3

在一般情况下,你无法这样做。C预处理器并不是那么灵活的。

你可能会有类似于

#define EXTRACT_N(N,A) EXTRACTTHEM ## N(A)

和拥有

#define EXTRACTTHEM1(X, ...) X
#define EXTRACTTHEM2(X,Y, ...) X,Y

等等

生成这样的宏集合非常容易,大小可以是任意的,但有限制。

比如说,有比cpp更强大的处理器,例如m4gpp

您可以考虑通过自己的脚本或某个生成器来生成C或C++代码,并让您的构建系统(例如Makefile)负责从不同的内容生成C代码。


嗯,你自相矛盾,一方面说这是不可能的,另一方面却展示了一个可行的例子。这就是我在我的代码中所做的方式,但我很好奇是否有更好的解决方案(也许可以使用boost预处理器)。除了C预处理器之外,我绝对不关心其他任何事情,因为这段代码是真实的C/C++项目的一部分。 - Pavel P
我编辑了问题,展示了我想要避免的迭代方法。 - Pavel P
我认为你有一个很好的理由在其他地方生成C++代码(也许使用gpp,它似乎对cpp友好)。 - Basile Starynkevitch
不,我不能这样做,因为我在一些C++代码中使用了那个宏,并且没有其他方法可以替代它(换句话说,项目不会接受)。我会接受你的答案,但我觉得应该有一些奇妙的解决方案来完成它(就像计算参数数量一样)。 - Pavel P
只需在一个#include的头文件中生成#define EXTRACTTHEM1 ... #define EXTRACTTHEM100即可。这就足够了... - Basile Starynkevitch
我明白你的意思,我不需要那么多(最多16个就可以了),但是我必须生成一些类似的循环,并且在想是否有更好的方法。如果我需要生成什么东西,我会编写一个C++的Hello World应用程序来为我完成这项工作 ;) - Pavel P

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接