Обратите внимание, что значение, которое Вы форматируете, должно быть числовым. Не похоже, что это возьмет строковое представление числа, и формат с запятыми.
As others noted, __COUNTER__
is the easy but nonstandard way of doing this.
If you need extra portability, or for other cool preprocessor tricks, the Boost Preprocessor library (which works for C as well as C++) will work. For example, the following header file will output a unique label wherever it's included.
#include <boost/preprocessor/arithmetic/inc.hpp>
#include <boost/preprocessor/slot/slot.hpp>
#if !defined(UNIQUE_LABEL)
#define UNIQUE_LABEL
#define BOOST_PP_VALUE 1
#include BOOST_PP_ASSIGN_SLOT(1)
#undef BOOST_PP_VALUE
#else
#define BOOST_PP_VALUE BOOST_PP_INC(BOOST_PP_SLOT(1))
#include BOOST_PP_ASSIGN_SLOT(1)
#undef BOOST_PP_VALUE
#endif
BOOST_PP_CAT(my_cool_label_, BOOST_PP_SLOT(1)):
Sample:
int main(int argc, char *argv[]) {
#include "unique_label.h"
printf("%x\n", 1234);
#include "unique_label.h"
printf("%x\n", 1234);
#include "unique_label.h"
return 0;
}
preprocesses to
int main(int argc, char *argv[]) {
my_cool_label_1:
printf("%x\n", 1234);
my_cool_label_2:
printf("%x\n", 1234);
my_cool_label_3:
return 0;
}
Если вы используете GCC или MSVC, есть __ COUNTER __
.
Кроме этого, вы можете сделать что-нибудь достойное рвоты, например:
#ifndef USED_1
#define USED_1
1
#else
#ifndef USED_2
#define USED_2
2
/* many many more */
#endif
#endif
Я не могу придумать способ их автоматического создания, но вы можете передать параметр в MAKE_LABEL:
#define MAKE_LABEL(n) my_cool_label_##n:
Тогда ...
MAKE_FUNNY_JUMPING_LOOP(
MAKE_LABEL(0);
MAKE_LABEL(1);
)
Это невозможно со стандартным препроцессором, хотя вы можете подделать это, поместив параметры в MAKE_LABEL или MAKE_FUNNY_JUMPING_LOOP и используя вставку токена в создать этикетку.
Ничто не мешает вам создать собственный сценарий предварительной обработки, который выполняет автоматическое приращение за вас. Однако в этом случае это не будет стандартный файл C / C ++.
Список доступных команд: http: //www.cppreference. com / wiki / preprocessor / start
Вы не можете использовать только один список, потому что вы не получите представления о глубине дерева. Таким образом, вам определенно понадобится два или более списка.
Вот моя попытка решения:
Используйте предварительный обход данных, чтобы узнать порядок данных. Это имеет смысл, потому что вы знаете, что первый узел находится наверху, и вы знаете, что данные, расположенные слева от обхода, принадлежат левой части дерева и т. Д.
Обход вашего почтового заказа может определять глубину дерева. Например, предположим, что у меня есть такая структура:
1
2 5 6
3 4 7
Where 2 is the parent of 3 and 4, and 5 is the parent of 7.
Preorder: 1 2 3 4 5 7 6
Postorder: 3 4 2 7 5 6 1
Мы знаем, что начинаем с 1, потому что это первый узел в обходе предварительного заказа. Затем мы смотрим на следующее число, 2. В почтовом порядке, поскольку число 2 идет ПЕРЕД узлом 1, мы знаем, что 2 должен быть дочерним по отношению к 1. Затем мы смотрим на 3. 3 идет перед 2, и, следовательно, 3 является дочерним элементом 2. 4 находится перед 2, но после 3, поэтому мы знаем, что 4 является дочерним элементом 2, но НЕ является дочерним элементом 3. И т. д.
Теперь это может не сработать, если узлы не уникальны, но в по крайней мере, это начало решения.
Изменить: Неясно, как ваш макрос «MAKE_FUNNY_JUMPING_LOOP»
ссылается на эти метки. Вы можете объяснить?
Я использую это:
#define MERGE_(a,b) a##b
#define LABEL_(a) MERGE_(unique_name_, a)
#define UNIQUE_NAME LABEL_(__LINE__)
int main()
{
int UNIQUE_NAME = 1;
return 0;
}
... и получаю следующее:
int main()
{
int unique_name_8 = 1;
return 0;
}