所以像其他人说的那样,不可以在宏中包含#include语句,因为预处理器只会传递一次。但是,您可以使预处理器使用最近发现自己使用的粗糙技巧来做基本相同的事情。
认识到预处理器指令不会在宏内执行任何操作,但它们会在文件中执行某些操作。所以,你可以将你想要改变的代码块粘贴到一个文件中,把它看作是一个宏定义(可以用其他宏修改),然后在不同的地方包含这个伪宏文件(make确定它没有包括警卫!)。它的行为不像一个宏,但它可以实现一些非常类似宏的结果,因为#include基本上只是将一个文件的内容转储到另一个文件中。
例如,考虑包含许多类似命名的标头,这些标头会分组。将它们全部写出来,或者甚至它们是自动生成的都很乏味。
辅助宏头:
/* 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修改),就像一个由冰坚请求:macro definition containing #include directive
我还没有广泛使用这个技巧,但它使我的工作完成。显然,它可以根据需要扩展为具有尽可能多的“参数”,并且您可以在其中运行您喜欢的任何预处理器命令,并生成实际的代码。你不能使用它创建的东西作为另一个宏的输入,就像你可以使用普通的宏一样,因为你不能将include包含在宏中。但它可以进入另一个伪宏:)。
其他人可能对其他限制有一些评论,并可能出错:)。
你应该看看模板(如stbuton建议)。你当然应该避免需要这样做。 – 2008-11-05 22:42:55
作为一般规则,您应该将所有#include语句放在同一个地方(通常是顶部)。它使维护和调试代码更简单。 – helloandre 2008-11-06 01:30:20
我有一个基本上你想做的事情(使用预处理器)有点疯狂的方式;请参阅我的回答:) http://stackoverflow.com/a/27830271/1447953 – 2015-01-07 23:17:27