Variadic macros with zero arguments, and commas

Consider this macro:

#define MAKE_TEMPLATE(...) template <typename T, __VA_ARGS__ >

When used with zero arguments it produces bad code since the compiler expects an identifier after the comma. Actually, VC's preprocessor is smart enough to remove the comma, but GCC's isn't. Since macros can't be overloaded, it seems like it takes a separate macro for this special case to get it right, as in:

#define MAKE_TEMPLATE_Z() template <typename T>

Is there any way to make it work without introducing the second macro?

9
задан Brian Tompsett - 汤莱恩 26 February 2016 в 19:58
поделиться

3 ответа

Нет, потому что вызов макроса MAKE_TEMPLATE () вообще не имеет нулевых аргументов; у него есть один аргумент, содержащий ноль токенов.

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

Чтобы ответ, приведенный ниже, работал, определите дополнительный параметр макроса перед многоточием:

   #define MAKE_TEMPLATE(UNUSED, ...) template <typename T, ## __VA_ARGS__ >

, а затем всегда ставьте запятую перед первым аргументом, если список не пуст:

   MAKE_TEMPLATE(, foo )

Старый ответ

Согласно http://gcc.gnu.org/onlinedocs/gcc/Variadic-Macros.html , GCC поддерживает это, но не прозрачно.

Синтаксис:

   #define MAKE_TEMPLATE(...) template <typename T, ## __VA_ARGS__ >

В любом случае, оба также поддерживают вариативные шаблоны в режиме C ++ 0x, что намного предпочтительнее.

12
ответ дан 4 December 2019 в 15:10
поделиться

В случае GCC нужно написать так:

#define MAKE_TEMPLATE(...) template <typename T, ##__VA_ARGS__ >

If __VA_ARGS__ пусто, препроцессор GCC удаляет предыдущую запятую.

1
ответ дан 4 December 2019 в 15:10
поделиться

Прежде всего имейте в виду, что макросы с переменным числом переменных не являются частью текущей версии C++. Кажется, они будут в следующей версии. На данный момент они соответствуют только в том случае, если вы программируете на C99.

Что касается вариативных макросов с нулевыми аргументами, существуют приемы а-ля boost, чтобы обнаружить это и обработать это макропрограммой. Google для пустых макроаргументов.

0
ответ дан 4 December 2019 в 15:10
поделиться