With a variant of code from Is it possible to iterate over arguments in variadic macros?
, you might do:
#define CONCATENATE(arg1, arg2) CONCATENATE1(arg1, arg2)
#define CONCATENATE1(arg1, arg2) CONCATENATE2(arg1, arg2)
#define CONCATENATE2(arg1, arg2) arg1##arg2
#define FOR_EACH_BY_PAIR_2(what, x, y)\
what(x, y)
#define FOR_EACH_BY_PAIR_4(what, x, y, ...)\
what(x, y)\
FOR_EACH_BY_PAIR_2(what, __VA_ARGS__)
#define FOR_EACH_BY_PAIR_6(what, x, y, ...)\
what(x, y)\
FOR_EACH_BY_PAIR_4(what, __VA_ARGS__)
#define FOR_EACH_BY_PAIR_8(what, x, y, ...)\
what(x, y)\
FOR_EACH_BY_PAIR_6(what, __VA_ARGS__)
#define NARG(...) NARG_(__VA_ARGS__, RSEQ_N())
#define NARG_(...) ARG_N(__VA_ARGS__)
#define ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, N, ...) N
#define RSEQ_N() 8, 7, 6, 5, 4, 3, 2, 1, 0
#define FOR_EACH_BY_PAIR_(N, what, ...) CONCATENATE(FOR_EACH_BY_PAIR_, N)(what, __VA_ARGS__)
#define FOR_EACH_BY_PAIR(what, ...) FOR_EACH_BY_PAIR_(NARG(__VA_ARGS__), what, __VA_ARGS__)
Limit is currently 8, up to you to increase that.
and then, you specific part:
#define MAKE_PAIR(x, y) COMMA my_pair<x, y>{}
#define COMMA ,
#define pair_off(p1, p2, ...) my_pair<p1, p2>{} FOR_EACH_BY_PAIR(MAKE_PAIR, __VA_ARGS__)
Demo