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

问题描述 投票:0回答:1

我需要不断更改

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

#define NUMBER 23

#include "file${NUMBER}.h"

int main()
{
    return run();
}
//Inside header files:
#pragma once
int run();

我知道我可以将

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

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

我正在使用 Visual Studio。

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

#define s1 "file"
#define s2 "23"
#define concat(a,b) a##b
#define s3 concat(s1,s2)
#include s3
c++ c-preprocessor
1个回答
4
投票

这不是“文本宏”,而是宏定义。

${NUMBER}
是 C++ 标准中未定义的预处理器指令语法,不能直接使用引号。

如果您阅读

#include
指令的文档,您会遇到类似的情况

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

在一系列实现定义的位置中搜索由

X
Y
分隔符之间的指定序列唯一标识的标头

其中

X

Y
<
>
 或引号 
"
。那里的文字是逐字使用的。

解决这个问题的唯一方法是对整个序列使用宏定义,有时某些库会使用宏定义,例如通过升压。这种形式的

#include

看起来像

#include pp-tokens new-line


其中

pp-tokens

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

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

// #define NUMBER 23 // rather use -D compiler flag? // ## operator is concatenation operator // which joins verbatim parameter with surrounding // text to form something lexem-like #define FILE_NAME_NUM(f,N) f##N.h // # is stringization operator which can be used only on a parameter #define STRINGIFY_(s) #s // this is required to process the paramater `macro` before # would // surround it by quotes #define STRINGIFY(macro) STRINGIFY_(macro) #define NUMBERED_HEADER(f,N) STRINGIFY(FILE_NAME_NUM(f,N)) // unfolds into #include "file23.h" #include NUMBERED_HEADER(file,NUMBER)
看起来有些多余,但这是必要的,因为预处理器使用了非常简单的替换算法。类似函数的宏定义不是函数。

预处理器的作用:

  1. 遇到

    NUMBERED_HEADER(file,NUMBER)

    ,会寻找文件和
    NUMBER
    的替代品。

  2. 找到

    NUMBER

    ,将其替换为23,结果:
    NUMBERED_HEADER(file,23)
    
    

  3. 它会搜索

    NUMBERED_HEADER

     并通过替换每个参数来将其替换为 
    STRINGIFY(FILE_NAME_NUM(file,23))
    
    

  4. 它会搜索

    FILE_NAME_NUM

     并通过替换每个参数来将其替换为 
    file23.h
    
    

  5. macro

     中的 
    STRINGIFY(macro)
     替换为 
    file23.h
    
    

    由于
  6. s
  7. 运算符

    STRINGIFY(s)
    中的
    "file23.h"
    #
    替换

对于 V 形

<

>
 会更简单,可以直接使用:

// still required for ## #define FILE_NAME_NUM(f,N) f##N.h #define NUMBERED_HEADER(f,N) <FILE_NAME_NUM(f,N)>
    
© www.soinside.com 2019 - 2024. All rights reserved.