Как создать список всех вхождений макроса?

У меня есть несколько объявлений struct, которые помечены макросом COMPONENT. Я хотел бы построить список типов из этих объявлений. Учитывая этот код:

// a.hpp

COMPONENT(A) {
  // struct body
};

// bc.hpp

COMPONENT(B) {
  // struct body
};
COMPONENT(C) {
  // struct body
};

Я хотел бы создать кортеж, который выглядит так:

constexpr auto components = std::make_tuple(
  Comp<A>{“A”},
  Comp<B>{“B”},
  Comp<C>{“C”}
);

Порядок элементов в кортеже не имеет значения. Мне также придется вручную включить все заголовки, содержащие объявления COMPONENT.

Я мог бы написать скрипт Python, который генерирует файл во время сборки, но я хотел бы сделать это с препроцессором, если это возможно. Я не думаю, что это возможно, но я видел, как люди делают какие-то сумасшедшие вещи с препроцессором, поэтому я решил спросить. Я не понимаю метапрограммирование макросов так же хорошо, как понимаю метапрограммирование шаблонов.

Что именно вы планируете делать с этой информацией? Возможно, есть лучший способ добиться того, что вы в конечном итоге пытаетесь сделать…

Michael Kenzel 06.04.2019 23:43

@MichaelKenzel Общая десериализация. Когда я читаю «B» в файле, я знаю, что должен десериализовать структуру B.

Indiana Kernick 06.04.2019 23:45

@MichaelKenzel Раньше я просто писал список вручную. Я хотел бы автоматизировать это с помощью препроцессора.

Indiana Kernick 06.04.2019 23:46

Вы можете взглянуть на протобуф

Michael Kenzel 06.04.2019 23:52

@MichaelKenzel На первый взгляд кажется, что protobuf не поддерживает полиморфизм, которого я могу добиться, написав список типов.

Indiana Kernick 06.04.2019 23:55

@ Kerndog73 «На первый взгляд кажется, что protobuf не поддерживает полиморфизм, которого я могу добиться, написав список типов». Ну, по крайней мере, protobuf может работать с расширения, это не совсем то же самое, что полиморфизм, но очень похоже, и хорошо разработано для определения протокольные сообщения и их анализа.

πάντα ῥεῖ 07.04.2019 00:07
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
6
35
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы не можете сделать это с самим препроцессором C. Он очень ограничен и не поддерживает полноценный скриптовый язык — ни в коем случае.

Ваши два курса действий:

  1. Использование внешнего интерфейса компилятора для получения синтаксического дерева предварительной обработки (clang может позволить вам это сделать; менее уверен в GCC)
  2. Использование скрипта Python/Perl/bash/awk/sed для поиска вариантов использования макроса.

Вариант 1 требует гораздо больше усилий (если только вы не можете адаптировать другой существующий инструмент), но он точен; вариант 2 требует небольших усилий, но довольно неточен без «изобретения велосипеда» - с ложными срабатываниями (например, имена макросов в строках) и, возможно, также ложными срабатываниями (например, макрос применяется внутри макроса, когда его имя генерируется путем объединения идентификаторов) .

Другие вопросы по теме