Bin*_*ian 34 c c++ macros c-preprocessor
有没有办法定义一个#include
在其体内包含指令的宏?
如果我只是把" #include",它给出了错误
C2162: "expected macro formal parameter"
Run Code Online (Sandbox Code Playgroud)
因为在这里我不是#用来连接字符串.
如果我使用" \# include",那么我收到以下两个错误:
error C2017: illegal escape sequence
error C2121: '#' : invalid character : possibly the result of a macro expansion
Run Code Online (Sandbox Code Playgroud)
有帮助吗?
Ben*_*mer 21
就像其他人说的那样,不,你不能在宏中包含#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
Run Code Online (Sandbox Code Playgroud)
伪宏文件
/* 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
Run Code Online (Sandbox Code Playgroud)
源文件
/* 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.
Run Code Online (Sandbox Code Playgroud)
这些包括甚至可能在你想要重复的代码块的中间(改变了FOO),因为Bing Jian的答案要求:包含#include指令的宏定义
我没有广泛使用这个技巧,但它完成了我的工作.它显然可以扩展为根据需要拥有尽可能多的"参数",并且您可以在那里运行您喜欢的任何预处理器命令,并生成实际代码.你不能使用它创建的东西作为另一个宏的输入,就像你可以使用普通的宏一样,因为你不能将包括在宏中.但它可以进入另一个伪宏:).
其他人可能对其他限制有一些评论,可能会出错:).
Dan*_*ett 13
我不会争论它的优点,但是freetype(www.freetype.org)做了以下事情:
#include FT_FREETYPE_H
Run Code Online (Sandbox Code Playgroud)
他们在其他地方定义FT_FREETYPE_H
C和C++语言明确禁止因宏扩展而形成预处理程序指令.这意味着您不能将预处理程序指令包含在宏替换列表中.如果你试图通过连接(和类似的技巧)"构建"一个新的预处理器指令来欺骗预处理器,那么行为是未定义的.
我相信C/C++预处理器只对代码进行一次传递,所以我认为这不会起作用.您可能能够通过宏将"#include"放在代码中,但编译器会阻塞它,因为它不知道如何处理它.对于你想要做的工作,预处理器必须对文件进行第二次传递才能获取#include.
hel*_*dre -2
为什么宏需要#include?如果您要 #include 宏所在的任何文件,则可以将 #include 与所有其余 #include 语句一起放在宏上方,一切都应该很好。
我认为没有理由让宏包含任何不能仅包含在文件中的内容。
| 归档时间: |
|
| 查看次数: |
34446 次 |
| 最近记录: |