Заставить препроцессор использовать предыдущее определение при переопределении

StackOverflow https://stackoverflow.com/questions/1384946

Вопрос

Обновление 3:

Неважно.Я вроде как получил то, что искал.Ниже приведены уникальные идентификаторы внутри класса.

static const int _counter_start = __COUNTER__;
static const int val1 = __COUNTER__ - _counter_start;
static const int val2 = __COUNTER__ - _counter_start;

Обновление 2:

Препроцессор повышения

Я буду реализовывать что-то вроде карты сообщений с этой функциональностью.

class a
{
...
    MAP_BEGIN()
    MAP_DECL...
    MAP_END()
...
};

Дело в том, что для каждого MAP_DECL мне нужно развернуть макрос в 2-х местах.

class a
{    
    virtual void func()
    {        
        ...
        //does something with the decl declaration        
    }
    ...
    //also expand some stuff here    
}

Препроцессор Boost должен (теоретически) позволять мне накапливать MAP_DECL в последовательность и расширять ее в func() в конце (одновременно расширяя поля класса по ходу дела).


Обновление 1:

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

Я пытаюсь расширить последовательности препроцессора Boost, но в данный момент я застрял в этом

#define SEQ (w)(x)(y)(z) 
#define SEQ2 BOOST_PP_SEQ_PUSH_BACK(SEQ, a)

Оригинал:

Предположим, у меня есть следующий код

#define CUR 2
#define CUR CUR + 2

Как заставить вторую строку использовать значение CUR из первой строки?

Это было полезно?

Решение

Короче говоря, нельзя.

В то время, когда CUR расширяется (после второго #define), препроцессор заменит экземпляр CUR на CUR + 2 и «закрасит» имя CUR синим цветом (не расширяя его дальше).После этого компилятор C видит CUR+2, что, скорее всего, приводит к ошибке компиляции.

Другие советы

Даже если бы вы могли это сделать, это опасно.
Пример:

#define CUR 2
#define CUR CUR + 2
...
int x = CUR*4; // x = 2 + 2 * 4

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

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

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

Вам практически необходимо определить всю последовательность или дать ей другое имя.

Вероятно, вы определяете какую-то переменную-член, а затем что-то делаете с ней в функции (регистрируетесь?).Если вы храните сообщения в контейнере, вы можете заставить MAP_DECL добавить в него сообщение, а затем в функции просто выполнить цикл for.

#define MAP_BEGIN std::vector<Message> m_messages; \
  void buildMap() {
#define MAP_END }
#define MAP_DECL(...) m_messages.push_back(...);

Если каждое сообщение имеет отдельный тип, попробуйте стереть тип (boost::any) или заставить их наследовать от некоторого базового класса и сохранить его.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top