8

最初我认为我需要这个,但我最终避免了它。然而,我的好奇心(以及对知识的渴望,哼)让我问:

预处理器宏可以吗,例如在

#include "MyClass.h"

INSTANTIATE_FOO_TEMPLATE_CLASS(MyClass)

扩展到另一个包括,例如

#include "MyClass.h"

#include "FooTemplate.h"
template class FooTemplate<MyClass>;

?

4

3 回答 3

14

我相信这是做不到的,这是因为预处理器是单通道的。所以它不能发出其他预处理器指令。

具体来说,来自 C99 标准(6.10.3.4 第 3 段):

3 生成的完全被宏替换的预处理标记序列不会作为预处理指令处理,即使它类似于一个,...

有趣的是,这就是为什么将一元运算_Pragma符添加到 c99 中的原因。因为#pragma不能由宏发出,但_Pragma可以。

于 2009-08-11T18:15:31.797 回答
10

C 标准说明了预处理指令(C99 - 6.10(2) - 预处理指令):

预处理指令由一系列预处理标记组成,这些标记以 # 预处理标记开头(在翻译阶段 4 开始时)...

(C99 - 6.10(7)):

除非另有说明,否则预处理指令中的预处理标记不受宏扩展的影响。

示例在:

#define EMPTY
EMPTY # include <file.h>

第二行的预处理标记序列不是预处理指令,因为它在翻译阶段 4 开始时不以 # 开头,即使在宏 EMPTY 被替换后它也会这样做

所以,不,宏不能扩展为“ #include”预处理指令。这些指令需要在翻译阶段 4 开始时就位(当处理这些指令发生预处理时)。由于宏扩展发生在第 4 阶段,宏不能导致某些东西在第 4 阶段开始时存在。

但是,我想指出,以下方法确实有效:

#ifdef WIN32
#define PLATFORM_HEADER "platform/windows/platform.h"
#else
#define PLATFORM_HEADER "platform/linux/platform.h"

#include PLATFORM_HEADER

因为 C 标准这么说(C99, 6.10.2(4) - 源文件包含):

形式的预处理指令

# include pp-tokens new-line

(与前两种形式之一不匹配)是允许的。指令中包含后的预处理标记的处理方式与普通文本一样。(当前定义为宏名称的每个标识符都被其预处理标记的替换列表替换。)

于 2009-08-11T18:42:53.037 回答
1

所有预处理器指令都在宏扩展开始之前进行解释,所以不,您不能将宏扩展为 #include 指令并对其进行解释。相反,它将被解释为(错误的)C++ 代码。

于 2009-08-11T20:22:36.800 回答