Как распечатать запятую несколько раз, используя Boost Preprocessor

Мне нужно использовать макрокоманду variadic для расширения до нескольких вариаций класса. Так как они должны иметь разные имена, основанные на вводе макросов, я не могу просто использовать шаблоны. Проблема в том, что я не могу расширить запятую (,), и в моем классе есть функции, которые принимают несколько параметров (для которых мне нужно использовать символ запятой).

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

Чтобы проиллюстрировать проблему, предположим, что у меня есть макрофункция, которая принимает переменное число параметров и выдает число запятых, равное количеству заданных ей параметров. Наивное решение было бы так:

#define TEST(...)\
BOOST_PP_REPEAT( \
BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), \
MACRO, \
BOOST_PP_VARIADIC_TO_TUPLE(__VA_ARGS__))

#define MACRO(z, n, data) BOOST_PP_IF(1,BOOST_PP_COMMA(),BOOST_PP_COMMA())\

Но это приводит к ряду ошибок, потому что запятая раскрывается и макрос думает, что они разделяют параметры.

Есть ли способ обойти эту проблему?

1

Решение

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

#define PRINT_COMMAS(...)\
BOOST_PP_REPEAT( \
BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), \
PRINT_COMMAS_MACRO, \
BOOST_PP_VARIADIC_TO_TUPLE(__VA_ARGS__))

#define PRINT_COMMAS_MACRO(z, n, data) ,

Смотри это работает

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

#define PRINT_COMMAS(...)\
BOOST_PP_ENUM( \
BOOST_PP_INC(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__)), \
BOOST_PP_TUPLE_EAT(), \
BOOST_PP_VARIADIC_TO_TUPLE(__VA_ARGS__))

Смотри это работает

Я лично думаю, что первое более понятно.

1

Другие решения


По вопросам рекламы ammmcru@yandex.ru
Adblock
detector