C++ 宏增加值,然后连接
我想创建一个递归宏,该宏将创建“next”类 例如:C++ 宏增加值,然后连接,c++,macros,concatenation,C++,Macros,Concatenation,我想创建一个递归宏,该宏将创建“next”类 例如: #define PRINTME(indexNum) class m_##(indexNum+1) { } indexNum+1被计算为int,不会连接到类名 在连接之前,我如何使编译器对其进行求值?简单的答案是不能。预处理器通常处理文本和标记;唯一的位置运算是在#if和#elif指令中执行的 此外,宏扩展不是递归的。在展开过程中,正在展开的宏被禁用,无法进行进一步替换。简单的答案是不能。预处理器通常处理文本和标记;唯一的位置运算是在#if和
#define PRINTME(indexNum) class m_##(indexNum+1) { }
indexNum+1
被计算为int
,不会连接到类名
在连接之前,我如何使编译器对其进行求值?简单的答案是不能。预处理器通常处理文本和标记;唯一的位置运算是在
#if
和#elif
指令中执行的
此外,宏扩展不是递归的。在展开过程中,正在展开的宏被禁用,无法进行进一步替换。简单的答案是不能。预处理器通常处理文本和标记;唯一的位置运算是在
#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...
在级联操作中不能只使用加上一(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__ { }
完成了
您考虑过使用模板吗?基于您的动机和忍受丑陋代码的能力,这是可行的。首先定义增量宏:
#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...
在级联操作中不能只使用加上一(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
时生成唯一的类名,那么以下是一种方法:
#define CONCATE1(X,Y) X##Y
#define CONCATE(X,Y) CONCATE1(X,Y)
#define PRINTME class CONCATE(m_,__COUNTER__) {}
\uuuu COUNTER\uuuu
是gcc中的一个扩展,我不确定它是否存在于其他编译器中。保证每次调用此宏时编译器都会添加1。(在这种情况下,您不能有效地使用
\uuuuu行
或\uuuu文件
。)
.如果您想在每次调用
PRINTME
时生成唯一的类名,那么以下是一种方法:
#define CONCATE1(X,Y) X##Y
#define CONCATE(X,Y) CONCATE1(X,Y)
#define PRINTME class CONCATE(m_,__COUNTER__) {}
\uuuu COUNTER\uuuu
是gcc中的一个扩展,我不确定它是否存在于其他编译器中。保证每次调用此宏时编译器都会添加1。(在这种情况下,您不能有效地使用
\uuuuu行
或\uuuu文件
。)
.我不确定您是否可以:预处理器只执行词法操作;它不知道C++的规则,也不知道表达式。我不确定你应该:可读性、可维护性等等。难道你不能把你的类放在列表或数组中吗?我可以用模板来处理这个问题。我只是想知道它是否可以用宏来完成,我不确定你是否可以:预处理器只执行词法操作;它不知道C++的规则,也不知道表达式。我不确定你应该:可读性、可维护性等等。难道你不能把你的类放在列表或数组中吗?我可以用模板来处理这个问题。我只是想知道是否可以用宏来完成。是的,我有一个使用模板的工作示例。我只是想知道宏,你是怎么找到我的anwser的?@Gwiazdorr这对我不起作用:我有什么不对的吗?你能粘贴一个工作示例吗?Thanks@YochaiTimmer你能把你的工作方案和模板一起寄给我吗?谢谢,我有一个使用模板的工作示例。我只是想知道宏,你是怎么找到我的anwser的?@Gwiazdorr这对我不起作用:我有什么不对的吗?你能粘贴一个工作示例吗?Thanks@YochaiTimmer你能把你的工作方案和模板一起寄给我吗?ThanksNice宏,不知道它存在。你们知道计数器是否是编译器时线程安全的吗?我的意思是,如果编译器同时处理8个文件,同一文件的计数器是否会连续?@YochaiTimmer,
\uuuu COUNTER\uuuu
发生在预处理阶段(甚至在编译开始之前),因此与线程安全无关。而且它在多个文件中总是唯一的。你们可以在测试程序中尝试一下。很好的宏,不知道它存在。你们知道计数器是否是编译器时线程安全的吗?我的意思是,如果编译器同时处理8个文件,同一文件的计数器是否会连续?@YochaiTimmer,\uuuu COUNTER\uuuu
发生在预处理阶段(甚至在编译开始之前),因此与线程安全无关。而且它在多个文件中总是唯一的。你可以在测试程序中尝试一下。