Создание и настройка имен и значений переменных через определения - PullRequest
0 голосов
/ 31 января 2012

Я пытаюсь создать дружественный интерфейс для класса ведения журнала в C ++.Конечной целью этого упражнения является создание единого определения, которое может меняться в зависимости от используемого уровня:

MODULE_LOG(name, LOG_ALARM);

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

MODULE_LOG(name, LOG_MESSAGE, LOG_ALARM);

Идея состоит в том, что код будет иметь определение печати, которое будет определено / undef, как запрошено в определении MODULE_LOG.Поэтому, если LOG_MESSAGE не был определен, то макрос печати сообщения будет определен как пустой, в противном случае, если он находится в списке, он напечатает.используя переменные.Моя идея состоит в том, чтобы создать набор переменных на основе переданных уровней. Например,

#define LOG_LEVEL(lvl,val) \
static int LOG_LEVEL_##lvl = val

Однако я столкнулся с другой проблемой, связанной с использованием макроса с переменными числами в C ++.Кажется, я не могу заставить макрос создавать несколько имен (т. Е. Пользователь передает LOG_MESSAGE и LOG_ALARM, создается только одно из них).Кроме того, мне не удалось динамически установить отдельные значения.

Итак, мои вопросы:

  1. Есть ли способ определить / отменить определение макроса печати с помощью определений?

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

Спасибо.

РЕДАКТИРОВАТЬ - не может использовать повышение.

Ответы [ 2 ]

2 голосов
/ 31 января 2012

Как насчет использования массива для захвата переменных?

enum LogLevel { LOG_ALARM, LOG_MESSAGE /*, ...*/, LOG_UNDEFINED};

#ifdef LOGGING_ENABLED
#define MODULE_LOG(name, ...) \
LogLevel levels[] = { __VA_ARGS__ , LOG_UNDEFINED } \
for(int i = 0; levels[i] != LOG_UNDEFINED; i++) \
    printLog(levels[i], name) // or something
#else
#define MODULE_LOG(name, ...)
#endif
0 голосов
/ 31 января 2012
  1. Нет. Вы не можете #define внутри макроса.
  2. Не напрямую. С некоторыми усилиями вы можете получить некрасивые и едва работающие макросы. Я действительно не рекомендую идти по этому пути, но здесь идет:

Первое, что вам нужно, это узнать, сколько параметров получает макрос. Прямого пути нет, но посмотрите на это (взято из здесь ):

#define VA_NUM_ARGS(...) VA_NUM_ARGS_IMPL(__VA_ARGS__, 5,4,3,2,1)
#define VA_NUM_ARGS_IMPL(_1,_2,_3,_4,_5,N,...) N

Теперь вы можете сделать что-то вроде:

#define CONCAT(a,b) a##b 
#define A(...) CONCAT(A,A_NUM_ARGS(__VA_ARGS__))(__VA_ARGS__)
#define A_1(x) something(x)
#define A_2(x, y) something_else(x, y)
...

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...