2

我想创建一个递归宏,它将创建“下一个”类。

例子:

#define PRINTME(indexNum) class m_##(indexNum+1) { }

indexNum + 1评估为int,并且不会连接到类名。

在连接之前,如何使编译器对其进行评估?

4

3 回答 3

5

如果您想在每次PRINTME调用时生成唯一的类名,则以下是一种方法:

#define CONCATE1(X,Y) X##Y
#define CONCATE(X,Y)  CONCATE1(X,Y)

#define PRINTME class CONCATE(m_,__COUNTER__) {}

__COUNTER__是 gcc 中的一个扩展,我不确定它是否存在于其他编译器中。保证每次调用此宏时编译器都会加 1。
(在这种情况下,您无法使用__LINE____FILE__有效。)

演示

于 2012-07-30T08:43:09.903 回答
4

简单的答案是你不能。预处理器一般处理文本和标记;唯一的算术是在 in#if#elif指令中进行的。

此外,宏扩展不是递归的。在扩展期间,正在扩展的宏被禁用,并且不可用于进一步替换。

于 2012-07-30T08:09:01.180 回答
2

嗯,这是可行的,这取决于你忍受丑陋代码的动力和能力。首先定义增量宏:

#define PLUS_ONE(x) PLUS_ONE_##x

#define PLUS_ONE_0 1
#define PLUS_ONE_1 2
#define PLUS_ONE_2 3
#define PLUS_ONE_3 4
#define PLUS_ONE_4 5
#define PLUS_ONE_5 6
#define PLUS_ONE_7 8
#define PLUS_ONE_8 9
#define PLUS_ONE_9 10
// and so on...

您不能只PLUS_ONE(x)在连接操作中使用,因为预处理器不会扩展它。但是,有一种方法 - 您可以滥用预处理器扩展可变参数的事实。

// pass to variadic macro to expand an argument
#define PRINTME(indexNum)       PRINTME_PRIMITIVE(PLUS_ONE(indexNum))
// do concatenation
#define PRINTME_PRIMITIVE(...)  class m_ ## __VA_ARGS__ { }

完毕!

PRINTME(1); // expands to class m_2 { };

您是否考虑过改用模板?

于 2012-07-30T08:37:10.987 回答