Можно ли заменить слово, используемое в аргументе, на макрос препроцессора?

Скажем, у меня есть макрос:

#define SUBST(MAGIC, ...) __VA_ARGS__  /* this won't work*/

И я хочу назвать это так:

SUBST(int, MAGIC a = 1);

// expected output:
int a = 1;

Есть ли какой-то набор диких косвенных обращений и расширений, которые я могу использовать для принудительного расширения MAGIC во втором аргументе со значением, которое зависит от вызова макроса?

Это происходит, когда другие аргументы поступают из другого слоя, а макрос SUBST повторяется много раз с разными значениями MAGIC.

Например:

#define WRAP(function, MAGIC, stuff, ...) \
  void function(__VA_ARGS__) { stuff };
#define SUPERWRAP(function, stuff, ...) \
    WRAP(function, uint8_t, stuff##_u8, __VA_ARGS__) \
    WRAP(function, uint16_t, stuff##_u16, __VA_ARGS__)

SUPERWRAP(example, EXAMPLE_IMPL, template_t<MAGIC>, int)

Что не может быть решено в шаблонах, потому что:

#define WRAP(function, stuff, ...) \
  template<class MAGIC>
  int function(__VA_ARGS__) { stuff }
WRAP(example, /*...*/, template_t<MAGIC>, int)

не допускает специализированной реализации, и использование типа в качестве аргумента шаблона в специализации является частичной специализацией, которая также является незаконной.

Единственный способ, которым я вижу, что макрос SUBST оценивает то, что вы хотите, — это использовать #define SUBST(MAGIC_PARAM, ...) using MAGIC = MAGIC_PARAM; __VA_ARGS__, но во многих контекстах это просто не сработает. Почему именно вы хотите использовать макрос здесь???

fabian 03.06.2023 21:50

Пожалуйста, добавьте пример, содержащий несколько различных желаемых примеров использования. Возможно, есть способ сделать это вообще без использования макросов. Пожалуйста, добавьте несколько из них к вопросу. (Должно быть как минимум 2 разных значения для первого аргумента макроса и несколько для 2, и всего более одного, чем 2 аргумента.)

fabian 03.06.2023 21:57

В исходном вопросе не было template, и он был макровопросом. Но теперь это больше похоже на вопрос C++. Должны ли вы настроить теги, чтобы отразить это?

Craig Estey 03.06.2023 22:04

Я не понимаю пример, просто WRAP(example, uint8_t, /*...*/, template_t<uint8_t>, int). Или #define WRAP2(a, b, c, ...) WRAP(a, b, c, template_t<b>, __VA_ARGS__)

KamilCuk 03.06.2023 22:10

@KamilCuk Я добавил еще один слой макроса, чтобы продемонстрировать, как __VA_ARGS__ многократно используется с разными типами (на практике в гораздо большем комбинаторном масштабе, но я думаю, что это иллюстрирует проблему).

sh1 03.06.2023 22:22

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

sh1 03.06.2023 22:28

@CraigEstey Изначально я сделал «простой пример» слишком простым, и мне было предложено удалить тег C++. Затем меня попросили привести более полный пример, и я чувствовал себя неловко, добавляя тег обратно. Но я предполагаю, что на данном этапе это вопрос C++.

sh1 03.06.2023 22:38
#define SUPERWRAP(function, stuff, ...) WRAP(function, uint8_t, stuff##_u8, template_t<uint8_t>, __VA_ARGS__). Это препроцессор - вы должны напечатать его. Если вам нужна строковая замена аргументов функции - это вне препроцессора C.
KamilCuk 03.06.2023 22:40
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
8
54
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Можно ли заменить слово, используемое в аргументе, на макрос препроцессора?

Нет, невозможно заменить слово, используемое в аргументе, на макрос препроцессора.

SUBST(int, MAGIC a = 1);
// expected output:
int a = 1;

Это невозможно.

Есть ли какой-то набор диких косвенных обращений и расширений, которые я могу использовать для принудительного расширения MAGIC во втором аргументе со значением, которое зависит от вызова макроса?

Нет.

Например: #define WRAP(функция, MAGIC, материал, ...) \

Использование макросов C для генерации определения функции приводит к сложному для чтения, сопровождения и отладки коду, который никто никогда не сможет исправить или сделать с ним что-либо позже. Подумайте о том, чтобы написать то, что вы хотите, построчно.

Вы можете рассмотреть возможность использования лучшего препроцессора, такого как jinja2, m4 или php.

Ни один из них не является жизнеспособным, когда я должен взаимодействовать с чужим кодом. Десятки тысяч строк копирования-вставки могут быть явными, но поддерживать их — жалкая работа.

sh1 03.06.2023 22:13

На самом деле, мой предыдущий комментарий не отражает истинного ужаса ситуации. Это не просто «чужой код», а интерфейс между чьим-то еще кодом и другим чьим-то кодом. Если бы это был только один кто-то другой, я бы просто поступил по-своему и пошел дальше.

sh1 03.06.2023 22:36

Я хочу сказать, что макросы C великолепны, но становятся неуправляемыми. Рассмотрим что-нибудь еще для генерации кода. Если становится сложно, значит, плохо.

KamilCuk 03.06.2023 22:43

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

sh1 03.06.2023 22:48

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

Похожие вопросы

Есть ли лучший/быстрый способ заполнить один вектор содержимым другого (меньшего) вектора, чем использовать цикл for?
Получить параметры из JavaThread* перед выполнением вызова
Есть ли способ проверить, что итератор std::ranges::views является конечным итератором только с помощью итератора?
Есть ли способ преобразовать символ, отличный от ascii, в целое число, а затем преобразовать это целое число обратно?
Приведение лямбда-выражения к объекту класса, конструктор которого принимает эту лямбду (краткая лямбда)
Qt QObject::connect приемник и слот разных классов
Зависимые имена против независимых имен
Что означает «безумие SSE 4.2» в документе с предложением «if consteval»?
Curl_formfree не работает должным образом, возвращает ошибку: SegFault
Как я могу связать программу C++ с программой Rust, а затем связать эту программу Rust обратно с программой C++? (cpp -> ржавчина -> cpp)