Так что, как другие говорят, нет, вы не можете иметь внутри макроса операторы #include, так как препроцессор делает только один проход. Тем не менее, вы можете заставить препроцессор делать то же самое с помощью хитрого трюка, который я недавно использовал.
Поймите, что директивы препроцессора ничего не будут делать внутри макроса, однако они будут делать что-то в файле. Таким образом, вы можете вставить блок кода, который вы хотите преобразовать в файл, думая о нем как о макроопределении (с фрагментами, которые могут быть изменены другими макросами), а затем #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), поскольку ответ на запрос Bing Jian: определение макроса, содержащее директиву #include
Я не использовал этот трюк широко, но он выполнил мою работу. Очевидно, что он может быть расширен так, чтобы иметь столько «параметров», сколько необходимо, и вы можете запускать там любые команды препроцессора, которые вам нравятся, плюс генерировать реальный код. Вы просто не можете использовать материал, который он создает, в качестве входных данных для другого макроса, как вы можете использовать обычные макросы, поскольку вы не можете вставить вставку внутри макроса. Но он может войти внутрь другого псевдомакроса:).
У других могут быть комментарии по поводу других ограничений, и что может пойти не так :).