Могу ли я использовать вставку токенов и / или строковое форматирование для #include?
Допустим, у меня есть несколько файлов с одинаковыми именами: Foo1Bar.h
, Foo2Bar.h
, Foo3Bar.h
и т. д. и т. д. Теперь я хочу автоматически включить те в некоторых main.c
в стиле "плагин", то есть я не хочу помнить #include
каждый. Возможно ли это сделать с помощью вставки токенов? Пока что у меня есть:
// this is the only line I want to have to change if I add Foo4Bar.h
#define FOR_EACH_FOOBAR(T) T(1)T(2)T(3)
//... somewhere else in my code
#define RUN_SOME_FUNC(T) Foo##T##Bar().run();
И вышесказанное работает нормально (при условии, конечно, все мои Foo*Bar.h
файлы имеют классы Foo*Bar
с общественностью run()
метод. (В случае, если это не ясно, мой пример здесь C++, но я не думаю, что сам вопрос, с #include
, является специфическим для C++).
У меня проблемы с дразнить, если я могу сделать это с моим #include
заявления также. Вместо
#include <Foo1Bar.h>
#include <Foo2Bar.h>
#include <Foo3Bar.h>
#include <Foo4Bar.h>
было бы лучше (для меня) изменить такие вещи, как:
FOR_EACH_FOOBAR(T) T(1)T(2)T(3)T(4)
FOR_EACH_FOOBAR(INCLUDE)
Я старался:
#define INCLUDE(T) #include <Foo##T##Bar.h>
но получите ошибку: '#' is not followed by a macro parameter
, потому что он пытается зачеркнуть начальную часть. Любая свертка или вращение, которые я пробовал, приводили к той же (или подобной) ошибке, и я не могу понять, как избежать #include
или что угодно, чтобы заставить это работать.
Возможно ли это, и если да, то как? Если нет, есть ли точная причина, почему нет?
2 ответа
Не совсем то, что вы хотите, потому что #
Команды обрабатываются препроцессором, и он не выглядит слишком #
Команда является результатом расширения, но есть некоторая функциональность для "генерации" #include
линии, они просто идут после #include
сам текст...
https://gcc.gnu.org/onlinedocs/cpp/Computed-Includes.html
Найдите здесь "#include что-либо еще": https://www.slac.stanford.edu/comp/unix/gnu-info/cpp_1.html
Вы не можете использовать:
#define INCLUDE(T) #include Foo##T##Bar.h
так как #
используется в качестве оператора для строкового аргумента.
#define STR(x) #x
char const* s = STR(THIS);
так же, как использование:
char const* s = "THIS";
При условии,
#define INCLUDE(T) #include Foo##T##Bar.h
страдает от проблемы, которая include
не является одним из параметров макроса. Следовательно, использование #include
не законно
Обновить
Я не думаю, что стандартная функциональность препроцессора C может быть использована для достижения того, чего вы хотите достичь. Лично я бы предпочел увидеть
#include <Foo1Bar.h>
#include <Foo2Bar.h>
#include <Foo3Bar.h>
#include <Foo4Bar.h>
в моем файле, чем
FOR_EACH_FOOBAR(T) T(1)T(2)T(3)T(4)
FOR_EACH_FOOBAR(INCLUDE)