Определить макрос внутри другого макроса

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

В настоящее время мне нужно написать это:

MyClass : public Base<MyClass> {
  Value<std::string> testString = value<std::string>(&MyClass::testString, "something");
  // many more values like this
}

И я хочу написать что-то вроде этого, чтобы уменьшить беспорядок из вышеизложенного:

BASE(MyClass) {
  VALUE(std::string, testString, "something");
}

Моим решением было бы определить два макроса стиля функции и BASE и VALUE, а внутри BASE определить еще одну константу с именем __CURRENT_CLASS, которая будет использоваться для всех вызовов VALUE. Но как мне определить эту константу в макросе BASE?

Если вы хотите избежать повторного ввода, приобретите утилиту нажатия клавиш, которая позволяет вам писать кучу текста одним нажатием клавиши. Или сделать реальные функции. typedef и using — хорошие способы создания синонимов (при использовании шаблонов, массивов или других структур данных). Макросы — это зло.

Thomas Matthews 01.06.2024 01:57

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

Thomas Matthews 01.06.2024 01:58

Существуют приложения, которые могут использовать UML или блок-схемы и генерировать на их основе код. Мой короткий путь — использовать трафаретные файлы, и я даже написал собственный генератор кода. Не помогает при отладке или исправлении проблем.

Thomas Matthews 01.06.2024 02:00

@ThomasMatthews Ваш комментарий о клавиатуре высокомерен. Вы понятия не имеете о навыках набора текста ОП. Разработка программного обеспечения в первую очередь требует много размышлений, и это то, что они практикуют.

DYZ 01.06.2024 02:01

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

Some programmer dude 01.06.2024 02:21

Кроме того, #undef имена ваших макросов #define перед ними, чтобы исключить возможные конфликтующие макросы из заголовков.

Christian Stieber 01.06.2024 02:29
__CURRENT_CLASS — зарезервированный идентификатор.
Eljay 01.06.2024 02:33

Моей первой мыслью было: «Почему макросы? Почему бы не использовать шаблоны с переменным числом вариантов?».

Jesper Juhl 01.06.2024 02:35

@DYZ Да, возможно, я стал высокомерным после того, как пошел на курсы клавиатуры, чтобы улучшить скорость набора текста. Использование функций или подпрограмм, чтобы мне не приходилось повторять код. Да, я нахожу эти #define ll long long и другие заявления ужасающими. Годы рекомендаций по кодированию и обзоров кода, в которых отвергаются макросы синонимов и сокращений, которые затрудняют понимание или чтение кода. Тратить бесчисленные часы на отладку из-за неисправных макросов. Макросы — это зло. Печатание — важный навык для разработчиков программного обеспечения, дизайнеров, архитекторов и документаторов.

Thomas Matthews 01.06.2024 02:35

@Brainiac синтаксис, который вам нужен для макросов, невозможен, в основном из-за завершающего { после BASE(MyClass). Если вы переместили { внутрь BASE(), то он сможет определять дополнительных членов класса. В любом случае, что именно value<std::string>(&MyClass::testString, ...) должен делать? Почему вы передаете указатель на Value, который все еще создается? Как на самом деле выглядит Value?

Remy Lebeau 01.06.2024 03:26

Это похоже на проблему XY с ошибочной попыткой сохранить некоторые нажатия клавиш, что делает вопрос вдвойне плохо мотивированным.

Passer By 01.06.2024 04:34

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

Brainiac 01.06.2024 07:52

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

BoP 01.06.2024 10:03

«иногда имеет смысл разгруппировать повторяющиеся строки», мы не можем сказать, потому что вы не описали реальную проблему. Это настолько маловероятно и редко, что кажется более вероятным, что вы делаете это неправильно, поэтому мы спрашиваем вас, в чем настоящая проблема.

Passer By 01.06.2024 10:18
Стоит ли изучать 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 называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
14
104
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Синтаксис не совсем тот же, но вы можете определить псевдоним типа, чтобы имя класса всегда было одним и тем же.

Невозможно определить макрос внутри макроса. Альтернатива, используемая, когда макросы очень сложны, состоит в том, чтобы #define указать некоторые параметры, которые будут использоваться, а затем #include заголовочный файл, содержащий определения макросов. Затем параметры можно переопределить и снова включить заголовок.

#include <string>
template <typename T> class Base {};
template <typename T> struct Value {};
template <typename T, typename Container>
Value<T> value(Value<T> Container::*, const T&);

#define BASE(name) \
  class name: public Base<name> { \
    using ThisClass = name;
#define ENDBASE(name) }

#define VALUE(name, type, init) \
  Value<type> name = value<type>(&ThisClass::name, init)
 
BASE(MyClass)
  VALUE(testString, std::string, "something");
ENDBASE(MyClass);

Но зачем тебе это делать???

Passer By 01.06.2024 04:30

Спасибо. Я решил это, не используя напрямую ваш подход, а вместо этого включил typedef в базовый класс, а не в макрос, который решил проблему.

Brainiac 01.06.2024 07:50

@PasserBy Я использую его для того, чтобы, во-первых, сэкономить себе немного времени на написании сотен строк «Value<type> name = ...», а во-вторых, это значительно улучшает читаемость.

Brainiac 01.06.2024 07:54

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

BoP 01.06.2024 09:59

— Зачем вымещать на мне свое неодобрение? потому что в результате получается ужасный код, независимо от того, как все началось.

Passer By 01.06.2024 10:12

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