Многоразовый препроцессор __COUNTER__ - PullRequest
4 голосов
/ 18 января 2011

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

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

Пример вкратце:

template<typename Functor, typename Tail>
struct node {
    typedef Functor head;
    typedef Tail tail;
};


template <typename Functor, typename Tail>
struct push_back {
    typedef node<Functor, Tail> list;
};

struct unit0 {};

#define AUTO_FUNCTION(name) struct test_functor_##name {            \
    static void run_test();                                         \
};                                                                  \
typedef push_back<                                                  \
            test_functor_##name,                                    \
            CONCAT(unit, PP_DEC(__COUNTER__))                       \
        >::list CONCAT(unit, __COUNTER__);                          \
void test_functor_##name::run_test()


AUTO_FUNCTION(hello) {
    ...
}

Теперь это работает, потому что я создал большой набор макросов препроцессора для PP_DEC, то есть:

#define PP_DEC(x) PP_DEC_I(x)
#define PP_DEC_I(x) PP_DEC_ ## x
#define PP_DEC_1 0
#define PP_DEC_2 1
...
#define PP_DEC_N N

Это та часть, которую я действительно хочу избежать, и причина, по которой я задаю этот вопрос. Есть ли у кого-нибудь предложение о том, как я могу использовать СЧЕТЧИК без увеличения его значения, или каким-либо другим способом я могу выполнить схему подсчета, похожую на:

 0 1
 1 2
 2 3
 ...

Предложения, которые изменяют семантику push_back и т. Д., Конечно, также приветствуются:).

PS. Это не предназначено для производства, только для развлечения. Так что GCC конкретные расширения приветствуются.

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

1 Ответ

11 голосов
/ 28 ноября 2012

Вы можете "исправить" значение __COUNTER__, используя дополнительный макрос:

#define MY_MACRO MY_MACRO_COUNTED(__COUNTER__)

#define MY_MACRO_COUNTED(counter) counter + counter
...