C++ 预处理器宏扩展到另一个预处理器指令
起初我以为我需要这个,但最终我避免了。然而,我的好奇心(以及对知识的渴望,哼)让我问: 可以使用预处理器宏,例如C++ 预处理器宏扩展到另一个预处理器指令,c++,macros,c-preprocessor,expansion,preprocessor-directive,C++,Macros,C Preprocessor,Expansion,Preprocessor Directive,起初我以为我需要这个,但最终我避免了。然而,我的好奇心(以及对知识的渴望,哼)让我问: 可以使用预处理器宏,例如 #include "MyClass.h" INSTANTIATE_FOO_TEMPLATE_CLASS(MyClass) 扩展到另一个include,如 #include "MyClass.h" #include "FooTemplate.h" template class FooTemplate<MyClass>; #包括“MyClass.h” #包括“FooT
#include "MyClass.h"
INSTANTIATE_FOO_TEMPLATE_CLASS(MyClass)
扩展到另一个include,如
#include "MyClass.h"
#include "FooTemplate.h"
template class FooTemplate<MyClass>;
#包括“MyClass.h”
#包括“FooTemplate.h”
模板类脚模板;
? 我认为这是不可能的,因为预处理器是单通的。因此它不能发出其他预处理器指令 具体而言,根据C99标准(6.10.3.4第3段): 3.由此产生的结果完全不同 宏替换的预处理令牌 序列未作为 预处理指令,即使它 像一个
有趣的是,这就是为什么c99中添加了一元的
\u Pragma
操作符。因为宏不能发出#pragma
,但是#pragma
可以。C标准对预处理指令(C99-6.10(2)-预处理指令)作了这样的规定:
预处理指令由一系列以开头的预处理标记组成
一个预处理标记(在翻译阶段4开始时)
及(C99-6.10(7)):
预处理指令中的预处理令牌不受宏的约束
扩展,除非另有说明
例如:
#define EMPTY
EMPTY # include <file.h>
因为C标准说明了这一点(C99,6.10.2(4)-源文件包含):
表单的预处理指令
# include pp-tokens new-line
(与前两种形式中的一种不匹配)是允许的。预处理
指令中包含后的标记的处理方式与普通文本中的处理方式相同。(各
当前定义为宏名称的标识符由其替换列表替换
预处理令牌。)
所有预处理器指令都是在宏展开开始之前解释的,因此,不可以将宏展开为#include指令并将其解释为这样。相反,它将被解释为(错误的)C++代码。 当然,它可以发出指令。它不能做的是在同一个预处理器过程中处理它们。因为
和##
字符在宏中有特殊的含义,我看不出您如何实际发出指令…实际上GCC预处理器似乎允许“#define X#ifdef X”,其中#ifdef和第二个X之间的空间实际上是换行,当你在上面运行cpp时,它实际上会发出一个#ifdef。其他人可能会对此进行检查,因为我刚刚喝了几杯啤酒:-)是的,似乎可以创建“类似”指令的东西,但标准明确规定(请参见我的编辑)这样的构造不作为指令处理。是的,我并不是说OP可以做他想做的事情。有一天,你会想把你的代码转移到一个操作系统上,比如Linux,在这个操作系统中,case是很重要的(即Foo.h和Foo.h是两个不同的文件),然后所有没有在Windows上发现的拼写错误都会得到解决。或者,如果你是Linux用户,总有一天你会想走另一条路,遇到不同但同样可怕的问题。我这样写是因为我想排除小写转换的问题(类名->文件名)。但这值得一提,谢谢+1.我们的规则是,文件名与类型和函数的命名方案完全匹配。我们和这里的提问者完全一样,类型名FooType将在FooType.h中定义。与任何“风格”指南一样,选择一种风格并坚持下去。话虽如此,我们在linux上进行了大量开发,因此操作系统会自动执行此规则……嗯……好的。那是个错误。我不喜欢在文件名中使用大写字母,但我喜欢在类型名中使用大写字母。但我应该为了这个问题写两个小写字母@Richard Corden:让文件系统和编译器强制执行该规则可能是暂时的,而其他OSs的任何端口都会完全擦除这种安全性。至少,在极权主义的小写文件名规则下,风险行为和错误会在任何问题发生之前立即显现出来。“莫阿拉,我更喜欢它。再想一想,我突然想到,无论您做什么(小写或混合大小写匹配内容),都需要由一些外部实用程序强制执行。总有可能有人会犯错误,除非您有操作系统支持(如我的情况),否则您必须通过一些脚本/工具来检查这一点。检查所有小写字母更容易,但检查名称是否与文件中的至少一个标识符匹配也不难您甚至可以使用一个静态分析工具来完成这项工作!!!;)我看了标准的这一部分,但我认为这不是最相关的部分。该示例不是试图发出指令的示例。相反,这是一个指令的示例,该指令前面没有“空格”(即使空宏解析为空格)。我同意您从标准中引用的内容更直接相关,但当我回答时,它并不存在。即使上面的例子与所问的不一样,在第4阶段开始时需要设置的预处理指令也不允许宏解释为有用的预处理指令,即使6.10.3.4(3)更直接地这样说。(换句话说,即使我不认为我的答案是错误的,你的答案显然是更好的)。对不起,但我必须选择一个好的答案。在你富有洞察力的评论上再加一个+1,尽可能公平,我希望你能理解。不需要道歉-埃文的回答肯定更好。即使不是这样,也没有必要道歉。您可能会得到这种印象,因为许多指令禁用了参数的宏扩展,但事实并非如此。宏
# include pp-tokens new-line