Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 宏增加值,然后连接_C++_Macros_Concatenation - Fatal编程技术网

C++ 宏增加值,然后连接

C++ 宏增加值,然后连接,c++,macros,concatenation,C++,Macros,Concatenation,我想创建一个递归宏,该宏将创建“next”类 例如: #define PRINTME(indexNum) class m_##(indexNum+1) { } indexNum+1被计算为int,不会连接到类名 在连接之前,我如何使编译器对其进行求值?简单的答案是不能。预处理器通常处理文本和标记;唯一的位置运算是在#if和#elif指令中执行的 此外,宏扩展不是递归的。在展开过程中,正在展开的宏被禁用,无法进行进一步替换。简单的答案是不能。预处理器通常处理文本和标记;唯一的位置运算是在#if和

我想创建一个递归宏,该宏将创建“next”类

例如:

#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
发生在预处理阶段(甚至在编译开始之前),因此与线程安全无关。而且它在多个文件中总是唯一的。你可以在测试程序中尝试一下。