有没有办法定义一个#include
在其体内包含指令的宏?
如果我只是把" #include
",它给出了错误
C2162: "expected macro formal parameter"
因为在这里我不是#
用来连接字符串.
如果我使用" \# include
",那么我收到以下两个错误:
error C2017: illegal escape sequence error C2121: '#' : invalid character : possibly the result of a macro expansion
有帮助吗?
就像其他人说的那样,不,你不能在宏中包含#include语句,因为预处理器只进行一次传递.但是,你可以让预处理器基本上做同样的事情,我最近发现自己使用了一个粗糙的技巧.
意识到预处理程序指令不会在宏内部执行任何操作,但是它们会在文件中执行某些操作.因此,您可以将想要变异的代码块粘贴到文件中,将其视为宏定义(可以通过其他宏更改的片段),然后在各个位置#include此伪宏文件(make确定它没有包含警卫!).它的行为与宏不完全相同,但它可以实现一些非常类似宏的结果,因为#include基本上只是将一个文件的内容转储到另一个文件中.
例如,考虑包含许多类似命名的标题组.将它们全部写出来,或者甚至是自动生成它们都很繁琐.您可以通过执行以下操作来部分自动化其包含:
Helper宏标题:
/* tools.hpp */ #ifndef __TOOLS_HPP__ #def __TOOLS_HPP__ // Macro for adding quotes #define STRINGIFY(X) STRINGIFY2(X) #define STRINGIFY2(X) #X // Macros for concatenating tokens #define CAT(X,Y) CAT2(X,Y) #define CAT2(X,Y) X##Y #define CAT_2 CAT #define CAT_3(X,Y,Z) CAT(X,CAT(Y,Z)) #define CAT_4(A,X,Y,Z) CAT(A,CAT_3(X,Y,Z)) // etc... #endif
伪宏文件
/* pseudomacro.hpp */ #include "tools.hpp" // NO INCLUDE GUARD ON PURPOSE // Note especially FOO, which we can #define before #include-ing this file, // in order to alter which files it will in turn #include. // FOO fulfils the role of "parameter" in this pseudo-macro. #define INCLUDE_FILE(HEAD,TAIL) STRINGIFY( CAT_3(HEAD,FOO,TAIL) ) #include INCLUDE_FILE(head1,tail1.hpp) // expands to #head1FOOtail1.hpp #include INCLUDE_FILE(head2,tail2.hpp) #include INCLUDE_FILE(head3,tail3.hpp) #include INCLUDE_FILE(head4,tail4.hpp) // etc.. #undef INCLUDE_FILE
源文件
/* mainfile.cpp */ // Here we automate the including of groups of similarly named files #define FOO _groupA_ #include "pseudomacro.hpp" // "expands" to: // #include "head1_groupA_tail1.hpp" // #include "head2_groupA_tail2.hpp" // #include "head3_groupA_tail3.hpp" // #include "head4_groupA_tail4.hpp" #undef FOO #define FOO _groupB_ #include "pseudomacro.hpp" // "expands" to: // #include "head1_groupB_tail1.hpp" // #include "head2_groupB_tail2.hpp" // #include "head3_groupB_tail3.hpp" // #include "head4_groupB_tail4.hpp" #undef FOO #define FOO _groupC_ #include "pseudomacro.hpp" #undef FOO // etc.
这些包括甚至可能在你想要重复的代码块的中间(改变了FOO),因为Bing Jian的答案要求:包含#include指令的宏定义
我没有广泛使用这个技巧,但它完成了我的工作.它显然可以扩展为根据需要拥有尽可能多的"参数",并且您可以在那里运行您喜欢的任何预处理器命令,并生成实际代码.你不能使用它创建的东西作为另一个宏的输入,就像你可以使用普通的宏一样,因为你不能将包括在宏中.但它可以进入另一个伪宏:).
其他人可能对其他限制有一些评论,可能会出错:).
我不会争论它的优点,但是freetype(www.freetype.org)做了以下事情:
#include FT_FREETYPE_H
他们在其他地方定义FT_FREETYPE_H
C和C++语言明确禁止因宏扩展而形成预处理程序指令.这意味着您不能将预处理程序指令包含在宏替换列表中.如果你试图通过连接(和类似的技巧)"构建"一个新的预处理器指令来欺骗预处理器,那么行为是未定义的.
我相信C/C++预处理器只对代码进行一次传递,所以我认为这不会起作用.您可能能够通过宏将"#include"放在代码中,但编译器会阻塞它,因为它不知道如何处理它.对于你想要做的工作,预处理器必须对文件进行第二次传递才能获取#include.