Заставить препроцессор использовать предыдущее определение при переопределении
-
21-09-2019 - |
Вопрос
Обновление 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) или заставить их наследовать от некоторого базового класса и сохранить его.