Как перегрузить макрос для одного и многих аргументов?

Мне надо написать макрос, который будет по-разному себя вести в зависимости от того, передали ему 1 аргумент или 2+. Как можно это сделать? Видел решения с перечислением кучи макросов (для 2, для 3, для 4 и т.д. аргументов), но хотелось бы найти решение без этого

#define MACRO_WITH_1_ARG(arg) /* impl 1 */
#define MACRO_WITH_N_ARGS(...) /* impl 2 */
#define MACRO(...) /* magic */

MACRO("test"); // calls 1
MACRO("test", 42); // calls 2

Ответы (1 шт):

Автор решения: HolyBlackCat

Возможно вам хватит просто #define FOO(arg, ...) и __VA_OPT__.

Но если нет, то:

#define CAT(x, y) CAT_(x, y)
#define CAT_(x, y) x##y

#define FOO(x, ...) CAT(DETAIL_FOO_,__VA_OPT__(0))(x __VA_OPT__(,) __VA_ARGS__)
#define DETAIL_FOO_(x) x // 1
#define DETAIL_FOO_0(x, ...) x, __VA_ARGS__ // 2

Интересная особенность: FOO(x,) ведет себя как FOO(x) (запятая, если после нее ничего нет, не считается за вызов с двумя аргументами). Это можно обойти, если мешает.

→ Ссылка