LINUX.ORG.RU

Кодогенерация define'ом, как заменить упоминание одного параметра в другом параметре его составом?

 ,


0

5

Можно ли в дефайне такого вида:

#define USE_CODE(CODE, NAME) CODE
при подстановке заменить упоминание в CODE имени NAME на содержимое параметра NAME?

Для примера:

USE_CODE( a.NAME = b.NAME, attr );
==>
a.attr = b.attr;

Более подробно, это для макроса FOREACH:


#define CNT_ARGS_PLACES(_1,_2,_3,_4,_5,_6,_7,_8,_9, n, ...) n
#define CNT_ARGS(...) CNT_ARGS_PLACES(__VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1)

#define USE_CODE(CODE, NAME) CODE

#define FOREACH_1(CODE, NAME, ...) USE_CODE(CODE, NAME)
#define FOREACH_2(CODE, NAME, ...) USE_CODE(CODE, NAME) FOREACH_1(CODE, __VA_ARGS__)
#define FOREACH_3(CODE, NAME, ...) USE_CODE(CODE, NAME) FOREACH_2(CODE, __VA_ARGS__)
#define FOREACH_4(CODE, NAME, ...) USE_CODE(CODE, NAME) FOREACH_3(CODE, __VA_ARGS__)

#define FOREACH_WRAP_NUM(N, CODE, ...) FOREACH_##N(CODE, __VA_ARGS__)
#define FOREACH_NUM(N, CODE,...) FOREACH_WRAP_NUM(N, CODE, __VA_ARGS__)

#define FOREACH(CODE, ...) FOREACH_NUM(CNT_ARGS(__VA_ARGS__), CODE, __VA_ARGS__)

И пример использования:
FOREACH( a.NAME = b.NAME;, attr1, attr2, attr3)

Или может готовые варианты уже есть?

Перемещено Shaman007 из desktop

Ответ на: комментарий от ox55ff

Пробуй на шаблонах цпп.

У меня и этого добра хватает. Но сейчас, нужен такой дефайн.

victor79 ()
Последнее исправление: victor79 (всего исправлений: 1)
Ответ на: комментарий от fsb4000

Не используй макросы в С++.

Ага, но это уклонение от ответа, с желанием казаться умным. Но фактические демонстрируешь свое не знание ответа на вопрос.

victor79 ()
Последнее исправление: victor79 (всего исправлений: 1)
Ответ на: комментарий от victor79

Но фактические демонстрируешь свое не знание ответа на вопрос.

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

В этом направлении движется и комитет, макросы выжигать огнём нужно, оставляя лишь для совместимости со старым кодом.

fsb4000 ★★★★★ ()
Ответ на: комментарий от fsb4000

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

Это вопрос.

Не используй макросы в С++

Это твой ответ. Не соответствует и глупо доказывать обратное.

victor79 ()
Ответ на: комментарий от victor79

Это твой ответ. Не соответствует и глупо доказывать обратное.

Ок, пожелаю тебе не найти ответа на твой вопрос. Не нужно увеличивать количество говнокода на С++…

fsb4000 ★★★★★ ()
Ответ на: комментарий от fsb4000

Не нужно увеличивать количество говнокода

Ой, а теперь еще доказываешь, что ты и твой код является эталоном правильности.

victor79 ()
Ответ на: комментарий от victor79

Ага, но это уклонение от ответа, с желанием казаться умным. Но фактические демонстрируешь свое не знание ответа на вопрос.

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

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

PS. Ещё раз, если ты не понял. Прямой ответ на твой вопрос - нельзя так сделать на препроцессоре, никак.

slovazap ★★★★★ ()
Ответ на: комментарий от slovazap

Не-не-не, это у тебя проблема XY

Давай посмотрим, что ты написал:

Ты хочешь что-то сделать и зачем-то используешь для этого макросы

Сам написал, что не знаешь, зачем я использую макросы.

которые для этого использовать нельзя

Для чего не знаешь, но использовать нельзя. Странно.

Кто поумнее видит это и советует не использовать

Интересно, как ты увидел, что другой поумней? Ты замерял? (Сделать глупость, и быть глупым разные вещи).

Ты же настаиваешь на том чтобы тебе ответили

Я лишь сказал, что фраза ни каким образом не может являтся ответом на вопрос. Ты видишь требования к fsb4000, или к тебе, что бы лично вы ответили мне на вопрос?

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

Для чего будет использоваться этот макрос я не говорил. В прошлой теме попробовал расписать, так 90% ответов как раз пытались ответить те варианты, что я написал что не подходят.

victor79 ()

Перемещено Shaman007 из desktop

Надо было сразу в толксы.

LamerOk ★★★★★ ()

Это называют «X Macro».

USE_CODE изменить на:

#define USE_CODE(CODE, NAME) CODE(NAME)
Использовать так:
#define X(NAME) a.NAME = b.NAME;
FOREACH(X, attr1, attr2, attr3);
#undef X

fopen ★★ ()
Ответ на: комментарий от victor79

На этом форуме запрещён постинг вызывающе неверной информации, вы же в курсе?

t184256 ★★★★★ ()

да, готовое есть, boost.preprocessor мощь та еще...

только там нумерация с 0 идет, а не с 1, как вы хотите

#include <boost/preprocessor/repetition/repeat.hpp>

int main (int argc, char[]  argv*)
{
    struct st {
        int attr0;
        int attr1;
        int attr2;
    } a, b;
    #define A(z, n, text) (a.text ## n = b.text ## n);
    BOOST_PP_REPEAT(3, A, attr)
    return 0;
}

в принципе, если чутка подшаманить, то можно и с attr1 сделать начало:

#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/control/if.hpp>
#include <boost/preprocessor/facilities/empty.hpp>

int main (int argc, char[]  argv*)
{
    struct st {
	int attr1;
	int attr2;
	int attr3;
    } a, b;
    #define A(z, n, text) BOOST_PP_IF(n, (a.text ## n = b.text ## n);, BOOST_PP_EMPTY())
    BOOST_PP_REPEAT(4, A, attr)
    return 0;
}

xperious ★★ ()
Последнее исправление: xperious (всего исправлений: 2)
Ограничение на отправку комментариев: только для зарегистрированных пользователей