我想创建一个递归宏,它将创建“下一个”类。
例子:
#define PRINTME(indexNum) class m_##(indexNum+1) { }
被indexNum + 1
评估为int
,并且不会连接到类名。
在连接之前,如何使编译器对其进行评估?
我想创建一个递归宏,它将创建“下一个”类。
例子:
#define PRINTME(indexNum) class m_##(indexNum+1) { }
被indexNum + 1
评估为int
,并且不会连接到类名。
在连接之前,如何使编译器对其进行评估?
如果您想在每次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__
有效。)
演示。
简单的答案是你不能。预处理器一般处理文本和标记;唯一的算术是在 in#if
和#elif
指令中进行的。
此外,宏扩展不是递归的。在扩展期间,正在扩展的宏被禁用,并且不可用于进一步替换。
嗯,这是可行的,这取决于你忍受丑陋代码的动力和能力。首先定义增量宏:
#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 { };
您是否考虑过改用模板?