如何在处理器的包含指令中使用文本宏

Bro*_*der 2 c++ c-preprocessor

我需要不断更改#include头文件名(有很多),所以我需要类似这样的东西:

#define NUMBER 23

#include "file${NUMBER}.h"

int main()
{
    return run();
}
Run Code Online (Sandbox Code Playgroud)
//Inside header files:
#pragma once
int run();
Run Code Online (Sandbox Code Playgroud)

我知道我可以将其替换${NUMBER}23,但我不想手动执行此操作,因为我也将在其他代码行中使用它。另外,我不想在运行时包含所有这些。

如果这是不可能的,还有哪些其他简单的替代方法可以做到这一点?

我正在使用 Visual Studio。

我也尝试过这个,但没有成功:

#define s1 "file"
#define s2 "23"
#define concat(a,b) a##b
#define s3 concat(s1,s2)
#include s3
Run Code Online (Sandbox Code Playgroud)

Swi*_*Pie 5

它\xe2\x80\x99不是一个\xe2\x80\x9c文本宏\xe2\x80\x9d,它\xe2\x80\x99是一个宏定义。${NUMBER}是 C++ 标准中未定义的预处理器指令语法,并且不能直接使用引号。

\n

如果您阅读该#include指令的文档,您会遇到类似的情况

\n
\n

#include X h-char-sequence Y new-line

\n

在一系列实现定义的位置中搜索由XY分隔符之间的指定序列唯一标识的标头

\n
\n

其中XY<and>或者 引号"。那里的文字是逐字使用的。

\n

解决这个问题的唯一方法是对整个序列使用宏定义,有时某些库(例如 boost)会使用宏定义。这种形式#include看起来像

\n

#include pp-tokens new-line

\n

其中pp-tokens是合法序列,与文本中其他任何地方一样处理。它应该导致上述两种形式之一,否则#include指令的行为是未定义的 - 可能会导致错误,但某些实现会忽略空序列。

\n

要创建用引号括起来的文本,需要一定的技巧:

\n
// #define NUMBER 23  // rather use -D compiler flag?\n\n// ## operator is concatenation operator\n// which joins verbatim parameter with surrounding \n// text to form something lexem-like \n#define FILE_NAME_NUM(f,N) f##N.h\n\n// # is stringization operator which can be used only on a parameter\n#define STRINGIFY_(s) #s\n// this is required to process the paramater `macro` before # would\n// surround it by quotes\n#define STRINGIFY(macro) STRINGIFY_(macro)\n#define NUMBERED_HEADER(f,N)  STRINGIFY(FILE_NAME_NUM(f,N))\n\n// unfolds into #include "file23.h"\n#include NUMBERED_HEADER(file,NUMBER)\n
Run Code Online (Sandbox Code Playgroud)\n

它看起来过多,但它\xe2\x80\x99是必要的,因为预处理器使用非常简单的替换算法。类似函数的宏定义是\xe2\x80\x99t 函数。

\n

预处理器的作用:

\n
    \n
  1. 遇到时NUMBERED_HEADER(file,NUMBER),它会搜索文件 和 的替代品NUMBER

    \n
  2. \n
  3. 查找NUMBER,将其替换为 23,结果:NUMBERED_HEADER(file,23)

    \n
  4. \n
  5. 它通过替换每个参数来搜索NUMBERED_HEADER并替换它STRINGIFY(FILE_NAME_NUM(file,23))

    \n
  6. \n
  7. 它通过替换每个参数来搜索FILE_NAME_NUM并替换它file23.h

    \n
  8. \n
  9. macroinSTRINGIFY(macro)被替换为file23.h

    \n
  10. \n
  11. sSTRINGIFY(s)替换为"file23.h"由于#运算符

    \n
  12. \n
\n

对于 V 形<>会更简单,可以直接使用它们:

\n
// still required for ##\n#define FILE_NAME_NUM(f,N) f##N.h\n#define NUMBERED_HEADER(f,N) <FILE_NAME_NUM(f,N)>\n
Run Code Online (Sandbox Code Playgroud)\n