C \ C ++ препроцессор разные аргументы для перегруженных макросов - PullRequest
0 голосов
/ 27 июля 2011

Я хочу реализовать вход в мой проект. У меня есть макрос, что-то вроде

__LOG_TRACE(lg, expr,...) LOG_TRACE_STREAM(lg) << expr;

Итак, я хочу реализовать интерфейс для этого макроса - еще один макрос, но я хочу поддерживать 2 типа:

LOG_TRACE(msg);
LOG_TRACE(my_logger, msg);

У меня есть глобальный регистратор, и первый макрос напишет msg, используя глобальный регистратор. Второй макрос возьмет my_logger и напишет msg, используя его.

Я могу сделать это с помощью LOG_TRACE(msg, my_logger); - но это нехорошо, труднее читать в коде. Порядок аргументов в __LOG_TRACE не обязателен.

Upd: Я не имею в виду перегрузку макросов. Смотри - например, я могу сделать это

#define LOG_TRACE(...) __LOG_TRACE(__VA_ARGS__, current_active)

Теперь я могу написать

LOG_TRACE(msg);
LOG_TRACE(msg, logger);

но я хочу не msg,logger а logger,msg

Ответы [ 5 ]

4 голосов
/ 27 июля 2011

Перегрузка макросов не разрешена в C или C ++.Но есть обходные пути.Вот статья, которая поможет вам «перегрузить» ваш макрос: http://cplusplus.co.il/2010/08/31/overloading-macros/

2 голосов
/ 27 июля 2011

Если у вас нет переменного количества регистраторов, я рекомендую вам сделать макрос для каждого регистратора. бывший (LOG_TRACE_XML, LOG_TRACE_OUT, LOG_TRACE_TXT). Потому что проще, тем лучше.

Но лучший способ сделать это - иметь LOG_TRACE_ERROR / LOG_TRACE_WARNING / LOG_TRACE_INFO и управлять поведением этих макросов с помощью IPC или другого макроса (SET_MODE (XML / TXT / OUT)) *

1 голос
/ 27 июля 2011

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

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

0 голосов
/ 27 июля 2011

__VA_ARGS__ является расширением текущего стандарта C ++, но если вы хотите поиграть с этим, P99 имеет множество служебных макросов для достижения того, что вы хотите.В частности, макросы, которые реализуют условные выражения в зависимости от количества вызываемых аргументов.

#define LOG_TRACE(...)                    \
P99_IF_EQ_1(P99_NARG(__VA_ARGS__))        \
(LOG_TRACE_(my_logger, __VA_ARGS__))      \
(LOG_TRACE_(__VA_ARGS__))

P99 на самом деле не совместим с C ++, поэтому вам придется немного адаптировать вещи.

Кстатиидентификаторы, которые начинаются с _ и с заглавной буквы или другого подчеркивания, зарезервированы C и C ++.Двойные подчеркивания вообще не допускаются для C ++, потому что они могут помешать искажению имен.Так что вам лучше выбрать другое имя для вашего базового макроса.

0 голосов
/ 27 июля 2011

Почему бы не сделать его функцией + сделать и преобразовать макрос выражения в строку?

#define DO_AND_RETURN_STRING_EXPR(x) (x,#x)

ov(DO_AND_RETURN_STRING_EXPR(y))
ov(my_logger, DO_AND_RETURN_STRING_EXPR(y))

(обратите внимание, я не проверял этот код).

...