Я хочу создать один макрос, который будет работать по-разному, если у него есть параметры или НЕТ.
Например: есть две разные реализации ошибки печати:
// 1. Print message = check code
#define PRINT_IF(wasError) \
do { if (wasError) printf(#wasError); } while(false)
// 2. Throws an exception with formatted message
#define PRINT_TEXT_IF(wasError, format, ...) \
do { if (wasError) printf(format, ##__VA_ARGS__); } while(false)
И я хотел бы иметь один макрос для обоих случаев.
Я попытался создать глобальный макрос, который проверяет, имеет ли он параметр или нет, на основе подхода из Как посчитать количество аргументов, переданных функции, которая принимает переменное число аргументов? .
#define RANDOM_GUID "5c300a82-2fe8-4bd3-ad12-ef13fa7b4a82"
#define FIRST_ARG(a1, ...) a1
#define HAS_ARGS(...) FIRST_ARG(##__VA_ARGS__, RANDOM_GUID)
#define GLOBAL_PRINT_IF(wasError, ...) \
do { \
if (wasError) { \
if (HAS_ARGS(##__VA_ARGS__)==RANDOM_GUID ) \
PRINT_IF(wasError); \
else \
PRINT_TEXT_IF(wasError, __VA_ARGS__); \
} \
} while(false)
Я предполагаю, что, поскольку FIRST_ARG
всегда возвращает первый аргумент, он вернет RANDOM_GUID
, если ##__VA_ARGS__
пусто.
Но этот код не компилируется с ошибкой : вставка "." и «красный» не дает действительный токен предварительной обработки .
Я пытался поиграть с ##
до __VA_ARGS__
, но не получилось с expected primary-expression before ‘==’ token
в очереди
if (HAS_ARGS(__VA_ARGS__)==RANDOM_GUID )
Итак, что я делаю не так? Как правильно с этим бороться?