包含#include 指令的宏定义
有没有办法定义一个包含 #include
的宏指令在其正文中?
Is there a way to define a macro that contains a #include
directive in its body?
如果我只是把#include
",它给出了错误
If I just put
the "#include
", it gives the error
C2162: "expected macro formal parameter"
因为这里我没有使用 #
来连接字符串.
如果我使用# include
",则会收到以下两个错误:
since here I am not using #
to concatenate strings.
If I use "# include
", then I receive the following two errors:
error C2017: illegal escape sequence
error C2121: '#' : invalid character : possibly the result of a macro expansion
有什么帮助吗?
推荐答案
所以就像其他人说的,不,你不能在宏中包含 #include 语句,因为预处理器只执行一次.但是,您可以使用我最近发现自己使用的一个技巧,让预处理器完成基本相同的操作.
So like the others say, no, you can't have #include statements inside a macro, since the preprocessor only does one pass. However, you can make the preprocessor do basically the same thing with a gnarly trick I found myself using recently.
意识到预处理器指令不会在宏中执行任何操作,但是它们会在文件中执行某些操作.因此,您可以将要变异的代码块粘贴到文件中,将其视为宏定义(可以由其他宏更改的部分),然后在各个位置#include 这个伪宏文件(make确保它没有包括警卫!).它的行为与宏不完全一样,但它可以实现一些非常类似于宏的结果,因为#include 基本上只是将一个文件的内容转储到另一个文件中.
Realise that preprocessor directives won't do anything inside a macro, however they WILL do something in a file. So, you can stick a block of code you want to mutate into a file, thinking of it like a macro definition (with pieces that can be altered by other macros), and then #include this pseudo-macro file in various places (make sure it has no include guards!). It doesn't behave exactly like a macro would, but it can achieve some pretty macro-like results, since #include basically just dumps the contents of one file into another.
例如,考虑包含许多成组出现的类似名称的标头.将它们全部写出来很乏味,或者甚至它们是自动生成的.您可以通过执行以下操作部分自动化它们的包含:
For example, consider including lots of similarly named headers that come in groups. It is tedious to write them all out, or perhaps even they are auto-generated. You can partially automate their inclusion by doing something like this:
帮助宏标头:
/* 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指令的宏定义
These includes could even be in the middle of codes blocks you want to repeat (with FOO altered), as the answer by Bing Jian requests: macro definition containing #include directive
我没有广泛使用这个技巧,但它可以完成我的工作.它显然可以根据需要扩展为具有尽可能多的参数",并且您可以在其中运行您喜欢的任何预处理器命令,并生成实际代码.您不能将它创建的内容用作另一个宏的输入,就像使用普通宏一样,因为您不能将包含内容粘贴在宏中.但它可以进入另一个伪宏:).
I haven't used this trick extensively, but it gets my job done. It can obviously be extended to have as many "parameters" as needed, and you can run whatever preprocessor commands you like in there, plus generate actual code. You just can't use the stuff it creates as the input into another macro, like you can with normal macros, since you can't stick the include inside a macro. But it can go inside another pseudo-macro :).
其他人可能对其他限制有一些评论,以及可能出现的问题:).
Others might have some comments on other limitations, and what could go wrong :).
相关文章