макрос variadi c, который обрабатывает последний аргумент другим способом - PullRequest
0 голосов
/ 14 января 2020

Я бродил, если есть способ определить макрос c variadi, который обрабатывает свой последний аргумент другим способом.

Например, можно ли определить макрос, который печатает пользовательский разделитель после каждого аргумент за исключением последнего?

т.е. как определить MACRO:

MACRO(a, lot, of, bars)

Для того, чтобы произвести этот вывод:

a|lot|of|bars

(EDIT: было указано мне в комментариях, что случай , в качестве разделителя тривиален)

Ответы [ 2 ]

3 голосов
/ 14 января 2020

Вы можете применить трюк подсчета аргументов макроса. Для максимум пяти аргументов макроса (исходный ответ поддерживает 4 аргумента макроса, поэтому вы можете просмотреть различие, чтобы увидеть, как расширить макрос для дополнительных аргументов):

#define MACRO(...) MACRO_X(__VA_ARGS__,5,4,3,2,1)(__VA_ARGS__)

#define MACRO_X(_5,_4,_3,_2,_1,X,...) MACRO_##X

#define MACRO_5(X,...) X|MACRO_4(__VA_ARGS__)
#define MACRO_4(X,...) X|MACRO_3(__VA_ARGS__)
#define MACRO_3(X,...) X|MACRO_2(__VA_ARGS__)
#define MACRO_2(X,...) X|MACRO_1(__VA_ARGS__)
#define MACRO_1(X,...) X

Чтобы создать строку, вы можете использовать оператор stringify:

#define STR2(X) STR(X)
#define STR(X) #X

Итак:

puts(STR2(MACRO(a,lot,of,bars)));
2 голосов
/ 14 января 2020

Если выходные данные не нужно структурировать, то вы можете создать эквивалентное выражение относительно просто:

#define MACRO(...) BIGMACRO(__VA_ARGS__,0,0,0,0,0,0,0,0)
#define BIGMACRO(a0,a1,a2,a3,a4,a5,a6,a7,...) a0|a1|a2|a3|a4|a5|a6|a7

, поэтому MACRO(a,lot,of,bars) расширяется до a|lot|of|bars|0|0|0|0, который имеет тот же тип и значение, что и a|lot|of|bars.

...