Macro реализующее "скрытый дополнит." аргумент macro
От: Аноним  
Дата: 09.06.10 17:52
Оценка:
Здравствуйте.
Было такое macro, упрощенно:
#define DEFINE_TRANSACTION(T, NAME, ARGT)    static T NAME(ARGT arg){ \
    int encript = 0; /* encript result or no. Always 0 */ \
    T    result; \
    . . .
}

Раньше encript мог быть равен только 0, теперь он может принимать значения: 0 или 1; и соответственно его необходимо явно указывать. Добавлять новый параметр в DEFINE_TRANSACTION нельзя. Вводить новое macro, что-то типа:
#define DEFINE_TRANSACTION_EX(OPT, T, NAME, ARGT)    static T NAME(ARGT arg){ \
    int encript = OPT & ENCRIPT_OPT_MASK; \
    T    result; \
    . . .
}

крайне не желательно.

Было бы замечательно дать возможность пользователю macro писать так:
/* если encription не нужен; результат транзакции long long: */

 DEFINE_TRANSACTION(long long, Transaction1, const char*)
 /* должно разворачиваеться в: */
 staic long long Transaction1(const char* arg) {
     int encript = 0; /* do not encript result */
     long long result;
     . . .
 }

/* и так, если нужен; результат транзакции Encripted long long: */

 DEFINE_TRANSACTION(ENCRIPT(long long), Transaction2, const char*)
 /* должно разворачиваеться в: */
 staic long long Transaction2(const char* arg) {
    int encript = 1; /* encript result */ 
    long long result; 
     . . .
 }

Здесь ENCRIPT(long long) должно каким-то образом стать причиной того, что переменной encript будет присвоено значение 1.
т.е. мне необходимо переписать исходное macro DEFINE_TRANSACTION так:
#define DEFINE_TRANSACTION( T, NAME, ARGT )    static PULL_TYPE(T) NAME(ARGT arg) \
{ \
    int encript = PULL_ENCRIPT(T); \
    PULL_TYPE(T)    result; \
    . . .
}

Вопрос собственно с реализацией макросов PULL_ENCRIPT и PULL_TYPE.
PULL_ENCRIPT(T) должно разворачиваться в 0;
PULL_ENCRIPT(ENCRIPT(T)) --> 1;
PULL_TYPE(T) --> T;
PULL_TYPE(ENCRIPT(T)) --> T;

Мне кажется, что где-то я этот трюк видела, но не припомню где, а может просто кажется что видела
c macro
Re: Macro реализующее "скрытый дополнит." аргумент macro
От: Erop Россия  
Дата: 09.06.10 18:03
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Мне кажется, что где-то я этот трюк видела, но не припомню где, а может просто кажется что видела


Шаблоны писать можешь? Если да (язык какой?), то можно замутить что-то типа:

template<typename T> struct Encripted { typedef T Type; };

template<typename T> struct EncriptedTreats {
    enum { IsEncripted = false };
    typedef T Type;
};

template<typename T> struct EncriptedTreats< Encripted<T> > {
    enum { IsEncripted = true };
    typedef typename Encripted<T>::Type Type;
};

#define ENCRIPT( TYPE_NAME ) Encripted<TYPE_NAME>
#define DEFINE_TRANSACTION(T, NAME, ARGT)    static T NAME(ARGT arg){ \
    int encript = EncriptedTreats< T >::IsEncripted; \
    EncriptedTreats< T >::Type    result; \
    . . .                                       \
}
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: Macro реализующее "скрытый дополнит." аргумент macro
От: Vamp Россия  
Дата: 09.06.10 18:28
Оценка:
Можно сжульничать вот так:


#define ENCRIPT(T) T

#define PULL_ENCRIPT(arg) !strncmp(#arg, 7, "\"ENCRIPT")


#define DEFINE_TRANSACTION(T, NAME, ARGT)    static T NAME(ARGT arg){ \
    int encript = PULL_ENCRIPT(#T);\
    T result; \
}


DEFINE_TRANSACTION(long long, nocrypt, const char*);
DEFINE_TRANSACTION(ENCRIPT(long long), crypt, const char*);


даст:

static long long nocrypt(const char* arg){ int encript = !strncmp("\"long long\"", 7, "\"ENCRIPT"); long long result; };
static long long crypt(const char* arg){ int encript = !strncmp("\"ENCRIPT(long long)\"", 7, "\"ENCRIPT"); long long result; };



Жульничество тут в том, что encript вычисляется не на этапе компиляции, а в ран-тайм. Но в приведенном коде ничего не говорт о том, что это недопустимо.
Да здравствует мыло душистое и веревка пушистая.
Re[2]: Macro реализующее "скрытый дополнит." аргумент macro
От: PIla  
Дата: 09.06.10 20:14
Оценка:
Спасибо, Erop:

Шаблоны писать умеем, только язык в данном случае C
Re: Macro реализующее "скрытый дополнит." аргумент macro
От: Andrew S Россия http://alchemy-lab.com
Дата: 09.06.10 21:06
Оценка:
А>Было такое macro, упрощенно:
А>
А>#define DEFINE_TRANSACTION(T, NAME, ARGT)    static T NAME(ARGT arg){ \
А>    int encript = 0; /* encript result or no. Always 0 */ \
А>    T    result; \
А>    . . .
А>}
А>


Как то так, тоже упрощенно:

#include <boost/preprocessor/cat.hpp>

#define TRANSACTION_ENCRYPTION_TRANSACTION_ENCRYPTION 0,
#define TRANSACTION_ENCRYPTION_TRANSACTION_ENCRYPTION_TRANSACTION_ENCRYPT 1

#define TRANSACTION_ENCRYPTION(x) BOOST_PP_CAT(TRANSACTION_ENCRYPTION_, x),
#define TRANSACTION_ENCRYPTION_I(x) ( BOOST_PP_CAT(TRANSACTION_ENCRYPTION_, TRANSACTION_ENCRYPTION x) )


#define GET_TRANSACTION_ENCRYPTION_I(is_encrypt, ret_type) is_encrypt
#define GET_TRANSACTION_ENCRYPTION(x) GET_TRANSACTION_ENCRYPTION_I TRANSACTION_ENCRYPTION_I(x)

#define GET_TRANSACTION_RET_TYPE_I(is_encrypt, ret_type) ret_type
#define GET_TRANSACTION_RET_TYPE(x) GET_TRANSACTION_RET_TYPE_I TRANSACTION_ENCRYPTION_I(x)

#define ENCRYPT(x) (TRANSACTION_ENCRYPT) x

#define DEFINE_TRANSACTION(ret_type, name, arg_type) \
static GET_TRANSACTION_RET_TYPE(ret_type) name(arg_type arg) \
{ \
     int encrypt = GET_TRANSACTION_ENCRYTION(ret_type); \
     GET_TRANSACTION_RET_TYPE(ret_type) result; \
     return result; \
}


если бустовый препроцессор на С не работает или низзя, то cat оттуда легко изъять.
А синтаксис, если уж нельзя от макроса убежать, лучше изменить на DEFINE_TRANSACTION((ENCRYPT) param1, param2 etc).
Удачи.

PS а трюк в том числе использовался тут: http://www.rsdn.ru/article/files/libs/RPCLib.xml
Автор(ы): Andrew Solodovnikov, Mike Kostuyhin
Дата: 28.12.2008
Мы не проводили социологических исследований, но и без них очевидно, что C++-программисты в большинстве случаев предпочтут написать все, начиная чуть ли не с ОС. Библиотеки, которые широко используются, можно пересчитать по пальцам одной руки. Поэтому неудивительно, что в интернете можно найти целую кучу реализаций RPC, похожих на Microsoft DCOM. Данная статья, на первый взгляд, выглядит еще одной реализацией библиотеки удаленного доступа к объектам, однако данная библиотека обладает рядом особенностей, делающих ее описание заслуживающим внимания. Ее отличают от других высокая производительность, возможность легкой смены транспортного уровня, реализация без использования внешних утилит и совместимость со старыми компиляторами, например, VC++ 6.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[2]: Macro реализующее "скрытый дополнит." аргумент macro
От: PIla  
Дата: 09.06.10 21:49
Оценка:
Здравствуйте, Vamp, Вы писали:

V>Можно сжульничать вот так: . . .


Извиняюсь, что не уточнила, надо было это сразу сделать — хочется что бы всю 'работу' выполнил именно препроцессор. К томуже ни кто не запрещает пользователю обернуть DEFINE_TRANSACTION в свой макрос скажем:
#define DEFINE_MY_TRANSACTION(T, NAME) DEFINE_TRANSACTION(T, NAME, MY_PREFERED_ARGTYPE)

А при использовании DEFINE_MY_TRANSACTION вместо DEFINE_TRANSACTION, в предложенном Вами варианте, препроцессор 'развернёт' ENCRIPT(T) до DEFINE_TRANSACTION. Соответственно в PULL_ENCRIPT всегда будет приходить только T ("long long" в нашем примере).
Re[3]: Macro реализующее "скрытый дополнит." аргумент macro
От: Erop Россия  
Дата: 09.06.10 23:11
Оценка:
Здравствуйте, PIla, Вы писали:

PI>Спасибо, Erop:


PI>Шаблоны писать умеем, только язык в данном случае C

Не заметил в первоначальном сообщении.

А множество типов открытое?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: Macro реализующее "скрытый дополнит." аргумент macro
От: PIla  
Дата: 09.06.10 23:58
Оценка:
Здравствуйте, Erop, Вы писали:

E>А множество типов открытое?


Угу, в
#define DEFINE_TRANSACTION(T, NAME, ARGT) ...
и T и ARGT — любые типы в т.ч. пользовательские.
Re[2]: Macro реализующее "скрытый дополнит." аргумент macro
От: PIla  
Дата: 10.06.10 06:24
Оценка:
Здравствуйте, Andrew S, Вы писали:

AS>Как то так, тоже упрощенно:

AS>
AS>#include <boost/preprocessor/cat.hpp>

AS>#define TRANSACTION_ENCRYPTION_TRANSACTION_ENCRYPTION 0,
AS>#define TRANSACTION_ENCRYPTION_TRANSACTION_ENCRYPTION_TRANSACTION_ENCRYPT 1

AS>#define TRANSACTION_ENCRYPTION(x) BOOST_PP_CAT(TRANSACTION_ENCRYPTION_, x),
AS>#define TRANSACTION_ENCRYPTION_I(x) ( BOOST_PP_CAT(TRANSACTION_ENCRYPTION_, TRANSACTION_ENCRYPTION x) )


AS>#define GET_TRANSACTION_ENCRYPTION_I(is_encrypt, ret_type) is_encrypt
AS>#define GET_TRANSACTION_ENCRYPTION(x) GET_TRANSACTION_ENCRYPTION_I TRANSACTION_ENCRYPTION_I(x)

AS>#define GET_TRANSACTION_RET_TYPE_I(is_encrypt, ret_type) ret_type
AS>#define GET_TRANSACTION_RET_TYPE(x) GET_TRANSACTION_RET_TYPE_I TRANSACTION_ENCRYPTION_I(x)

AS>#define ENCRYPT(x) (TRANSACTION_ENCRYPT) x

AS>#define DEFINE_TRANSACTION(ret_type, name, arg_type) \
AS>static GET_TRANSACTION_RET_TYPE(ret_type) name(arg_type arg) \
AS>{ \
AS>     int encrypt = GET_TRANSACTION_ENCRYTION(ret_type); \
AS>     GET_TRANSACTION_RET_TYPE(ret_type) result; \
AS>     return result; \
AS>}

AS>

Спасибо, суть ясна. Это то, что и требовалось. Но теперь меня начинает беспокоить вопрос: а на сколько это переносимо? Дело в том, что в приведённом Вами виде, с учётом исправления опечатки в строке
int encrypt = GET_TRANSACTION_ENCRYTION(ret_type); \
на
int encrypt = GET_TRANSACTION_ENCRYPTION(ret_type); \
, код не компилируется GCC 4.5.0.

GCC 4.5.0 успешно компилирует в таком виде:
#define TRANSACTION_ENCRYPTION_TRANSACTION_ENCRYPTION 0,
#define TRANSACTION_ENCRYPTION_TRANSACTION_ENCRYPTION_TRANSACTION_ENCRYPT 1,

#define TRANSACTION_ENCRYPTION(x) BOOST_PP_CAT(TRANSACTION_ENCRYPTION_, x)
#define TRANSACTION_ENCRYPTION_I(x) BOOST_PP_CAT(TRANSACTION_ENCRYPTION_, TRANSACTION_ENCRYPTION x)


#define GET_TRANSACTION_ENCRYPTION_II(is_encrypt, ret_type) is_encrypt
#define GET_TRANSACTION_ENCRYPTION_I(x) GET_TRANSACTION_ENCRYPTION_II(x)
#define GET_TRANSACTION_ENCRYPTION(x) GET_TRANSACTION_ENCRYPTION_I (TRANSACTION_ENCRYPTION_I(x))

#define GET_TRANSACTION_RET_TYPE_II(is_encrypt, ret_type) ret_type
#define GET_TRANSACTION_RET_TYPE_I(x) GET_TRANSACTION_RET_TYPE_II(x)
#define GET_TRANSACTION_RET_TYPE(x) GET_TRANSACTION_RET_TYPE_I(TRANSACTION_ENCRYPTION_I(x))

#define ENCRYPT(x) (TRANSACTION_ENCRYPT) x

#define DEFINE_TRANSACTION(ret_type, name, arg_type) \
static GET_TRANSACTION_RET_TYPE(ret_type) name(arg_type arg) \
{ \
     int encrypt = GET_TRANSACTION_ENCRYPTION(ret_type); \
     GET_TRANSACTION_RET_TYPE(ret_type) result; \
     return result; \
}
Кстати фрагмент взятый отсюда: http://www.rsdn.ru/article/files/libs/RPCLib.xml
Автор(ы): Andrew Solodovnikov, Mike Kostuyhin
Дата: 28.12.2008
Мы не проводили социологических исследований, но и без них очевидно, что C++-программисты в большинстве случаев предпочтут написать все, начиная чуть ли не с ОС. Библиотеки, которые широко используются, можно пересчитать по пальцам одной руки. Поэтому неудивительно, что в интернете можно найти целую кучу реализаций RPC, похожих на Microsoft DCOM. Данная статья, на первый взгляд, выглядит еще одной реализацией библиотеки удаленного доступа к объектам, однако данная библиотека обладает рядом особенностей, делающих ее описание заслуживающим внимания. Ее отличают от других высокая производительность, возможность легкой смены транспортного уровня, реализация без использования внешних утилит и совместимость со старыми компиляторами, например, VC++ 6.

#define RPC_PARAM_RPC_PARAM_DIRECTION            RPC_PARAM_DIRECTION_AUTO,
#define RPC_PARAM_RPC_PARAM_DIRECTION_RPC_IN    RPC_PARAM_DIRECTION_IN
#define RPC_PARAM_RPC_PARAM_DIRECTION_RPC_OUT    RPC_PARAM_DIRECTION_OUT
#define RPC_PARAM_RPC_PARAM_DIRECTION_RPC_INOUT RPC_PARAM_DIRECTION_INOUT

#define RPC_PARAM_DIRECTION(x) PPC_CAT(RPC_PARAM_DIRECTION_, x),
#define RPC_PARAM_WITH_DIRECTION(x) PPC_CAT(RPC_PARAM_, RPC_PARAM_DIRECTION x)
без аналогичной правки тоже не компилируется. Подозреваю, что мой вариант не будет работать в VS. А есть и другие компиляторы, да и разные версии ещё. Эх, в общем будем пробовать.
А за идею и за то что меня "ткнули носом", ещё раз спасибо. А то у меня мЫшление всё как-то шло в другой плоскости
Re[3]: Macro реализующее "скрытый дополнит." аргумент macro
От: Andrew S Россия http://alchemy-lab.com
Дата: 10.06.10 07:08
Оценка:
PI>Спасибо, суть ясна. Это то, что и требовалось. Но теперь меня начинает беспокоить вопрос: а на сколько это переносимо? Дело в том, что в приведённом Вами виде, с учётом исправления опечатки в строке
int encrypt = GET_TRANSACTION_ENCRYTION(ret_type); \
на
int encrypt = GET_TRANSACTION_ENCRYPTION(ret_type); \
, код не компилируется GCC 4.5.0.


И не должен Там требуется дополнительный уровень перевызова — особенности препроцессора. Для MSVC без разницы.

PI> А за идею и за то что меня "ткнули носом", ещё раз спасибо. А то у меня мЫшление всё как-то шло в другой плоскости


Удачи.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[4]: Macro реализующее "скрытый дополнит." аргумент macro
От: Erop Россия  
Дата: 10.06.10 07:40
Оценка:
Здравствуйте, Andrew S, Вы писали:

AS>Удачи.


Возможно она пригодится
Не боитесь, такие тонкие особенности поведения препроцессора использовать? Как это потом поддерживать и переносить?

IMHO, надёжнее всего два макроса иметь.
Если над этим макросом ещё куча производных написана, и два макроса иметь плохо, то я бы typedef делал с каким-то фиксированным префиксом, и в CT его макросом бы проверял...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: Macro реализующее "скрытый дополнит." аргумент macro
От: sidorov18 США  
Дата: 10.06.10 08:06
Оценка:
Здравствуйте, Andrew S, Вы писали:

AS>
AS>#include <boost/preprocessor/cat.hpp>

AS>#define TRANSACTION_ENCRYPTION_TRANSACTION_ENCRYPTION 0,
AS>#define TRANSACTION_ENCRYPTION_TRANSACTION_ENCRYPTION_TRANSACTION_ENCRYPT 1

AS>#define TRANSACTION_ENCRYPTION(x) BOOST_PP_CAT(TRANSACTION_ENCRYPTION_, x),
AS>#define TRANSACTION_ENCRYPTION_I(x) ( BOOST_PP_CAT(TRANSACTION_ENCRYPTION_, TRANSACTION_ENCRYPTION x) )


AS>#define GET_TRANSACTION_ENCRYPTION_I(is_encrypt, ret_type) is_encrypt
AS>#define GET_TRANSACTION_ENCRYPTION(x) GET_TRANSACTION_ENCRYPTION_I TRANSACTION_ENCRYPTION_I(x)

AS>#define GET_TRANSACTION_RET_TYPE_I(is_encrypt, ret_type) ret_type
AS>#define GET_TRANSACTION_RET_TYPE(x) GET_TRANSACTION_RET_TYPE_I TRANSACTION_ENCRYPTION_I(x)

AS>#define ENCRYPT(x) (TRANSACTION_ENCRYPT) x

AS>#define DEFINE_TRANSACTION(ret_type, name, arg_type) \
AS>static GET_TRANSACTION_RET_TYPE(ret_type) name(arg_type arg) \
AS>{ \
AS>     int encrypt = GET_TRANSACTION_ENCRYTION(ret_type); \
AS>     GET_TRANSACTION_RET_TYPE(ret_type) result; \
AS>     return result; \
AS>}

AS>


А расскажите пожалуйста, как это работает. Непонятно, как макрос BOOST_PP_CAT(TRANSACTION_ENCRYPTION_, TRANSACTION_ENCRYPTION x) на выходе дает 2 аргумента, которые требуют макросы GET_TRANSACTION_ENCRYPTION_I/GET_TRANSACTION_RET_TYPE_I.

Если передавать ENCRYPT(int), то в BOOST_PP_CAT должно попасть BOOST_PP_CAT( TRANSACTION_ENCRYPTION_, TRANSACTION_ENCRYPTION (TRANSACTION_ENCRYPT) int ) так?
понятно, как макрос получает TRANSACTION_ENCRYPTION_TRANSACTION_ENCRYPTION_TRANSACTION_ENCRYPT, непонятно, как x(в данном случае int) становится вторым аргументом.

можно предположить, что препроцессор слово через пробел, не входящее в аргументы макроса передает как 2-й аргумент(x в данном случае как бы 3-й аргумент).
но пробую такой код:

#include<boost/preprocessor/cat.hpp>

#define get_type( type, name ) type

#define XXX(x) 

int main()
{
   get_type( BOOST_PP_CAT(in, t a) ) b = 1;
   return 0;
}

не работает:

error: macro "get_type" requires 2 arguments, but only 1 given

Re[5]: Macro реализующее "скрытый дополнит." аргумент macro
От: Andrew S Россия http://alchemy-lab.com
Дата: 10.06.10 12:05
Оценка:
AS>>Удачи.

E>Возможно она пригодится

E>Не боитесь, такие тонкие особенности поведения препроцессора использовать? Как это потом поддерживать и переносить?

В смысле? Реализацию, работающую на большинстве известных мне препроцессоров, сделать просто. А остальное — по мере необходимости.

E>IMHO, надёжнее всего два макроса иметь.


Это вопрос к требованиям. Не нам их определять, вопрос был поставлен четко.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[3]: Macro реализующее "скрытый дополнит." аргумент macro
От: Andrew S Россия http://alchemy-lab.com
Дата: 10.06.10 12:15
Оценка:
S>А расскажите пожалуйста, как это работает. Непонятно, как макрос BOOST_PP_CAT(TRANSACTION_ENCRYPTION_, TRANSACTION_ENCRYPTION x) на выходе дает 2 аргумента, которые требуют макросы GET_TRANSACTION_ENCRYPTION_I/GET_TRANSACTION_RET_TYPE_I.

Все дело в волшебных запятых

S>Если передавать ENCRYPT(int), то в BOOST_PP_CAT должно попасть BOOST_PP_CAT( TRANSACTION_ENCRYPTION_, TRANSACTION_ENCRYPTION (TRANSACTION_ENCRYPT) int ) так?

S>понятно, как макрос получает TRANSACTION_ENCRYPTION_TRANSACTION_ENCRYPTION_TRANSACTION_ENCRYPT, непонятно, как x(в данном случае int) становится вторым аргументом.

S>можно предположить, что препроцессор слово через пробел, не входящее в аргументы макроса передает как 2-й аргумент(x в данном случае как бы 3-й аргумент).


Тут дело не в этом. Просто разные пути вычисления в зависимости от наличия (MACRO) перед аргументом.

S>но пробую такой код:


Там все не так... Никакой магии с передачей аргументов тут нет — всего лишь используется свойство препроцессоров при обработке макроса вычислять аргументы, т.ч. выполняя получившиеся в результате раскрытия макросы. После раскрытия TRANSACTION_ENCRYPTION_I(x) получается (0, arg) либо (1, arg). Дальше все очевидно (ну, кроме того, что некоторых препроцессоров надо еще раз явно заставить раскрыть макросы, добавив вложенность вызовов, что делает по умолчанию BOOST_PP_CAT).
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[4]: Macro реализующее "скрытый дополнит." аргумент macro
От: sidorov18 США  
Дата: 10.06.10 12:28
Оценка:
Здравствуйте, Andrew S, Вы писали:

S>>А расскажите пожалуйста, как это работает. Непонятно, как макрос BOOST_PP_CAT(TRANSACTION_ENCRYPTION_, TRANSACTION_ENCRYPTION x) на выходе дает 2 аргумента, которые требуют макросы GET_TRANSACTION_ENCRYPTION_I/GET_TRANSACTION_RET_TYPE_I.


AS>Все дело в волшебных запятых


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

#define TRANSACTION_ENCRYPTION_TRANSACTION_ENCRYPTION 0,
#define TRANSACTION_ENCRYPTION_TRANSACTION_ENCRYPTION_TRANSACTION_ENCRYPT 1,

#define TRANSACTION_ENCRYPTION(x) BOOST_PP_CAT(TRANSACTION_ENCRYPTION_, x)//,
#define TRANSACTION_ENCRYPTION_I(x) ( BOOST_PP_CAT(TRANSACTION_ENCRYPTION_, TRANSACTION_ENCRYPTION x) )
Re[5]: Macro реализующее "скрытый дополнит." аргумент macro
От: Andrew S Россия http://alchemy-lab.com
Дата: 10.06.10 18:08
Оценка: :)
S>>>А расскажите пожалуйста, как это работает. Непонятно, как макрос BOOST_PP_CAT(TRANSACTION_ENCRYPTION_, TRANSACTION_ENCRYPTION x) на выходе дает 2 аргумента, которые требуют макросы GET_TRANSACTION_ENCRYPTION_I/GET_TRANSACTION_RET_TYPE_I.

AS>>Все дело в волшебных запятых


S>а.... разобрался. сначала запятые не заметил.

S>тогда для меньшего запутывания можно было бы запятую возле BOOST_PP_CAT(...), перемесить к определению единицы:

Да, так можно. Хотя, в таком коде меньше запутать уже вряд ли можно
http://www.rusyaz.ru/pr — стараемся писАть по-русски
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.