Variadic макросы с нулевыми аргументами и запятыми - PullRequest
9 голосов
/ 25 августа 2010

Рассмотрим этот макрос:

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

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

#define MAKE_TEMPLATE_Z() template <typename T>

Есть ли способ заставить его работать без введения второго макроса

Ответы [ 3 ]

12 голосов
/ 25 августа 2010

Нет, потому что вызов макроса 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 поддерживает это, но не прозрачно.

Синтаксисis:

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

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

1 голос
/ 25 августа 2010

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

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

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

0 голосов
/ 25 августа 2010

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

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

...