2

I wrote this variadic macro template<>-maker.

#define TNAME0()
#define TNAME1(_1)        typename _1
#define TNAME2(_1,_2)     typename _1, typename _2
#define TNAME3(_1,_2,_3)  typename _1, typename _2, typename _3
#define TYPENAMES(_0,_1,_2,_3,n,...) TNAME##n
#define T(types...)   template< TYPENAMES(,##types,3,2,1,0)(types) >

It works great with GNU C++ (e.g. T(),T(U),T(U,V),...), but fails with 0 args using ISO C++ standard (calls TYPES1 instead of TYPES0).

Is there a fix that works with both GNU and ISO c++?

codechimp
  • 1,509
  • 1
  • 14
  • 21

1 Answers1

3

This syntax for variadic macros isn't standard C++ at all:

#define T(types...)

Instead you can use an unnamed ..., which is referred to by __VA_ARGS__ in the expansion. Since C++20 you can also use __VA_OPT__(,) to include the initial , only if ... isn't empty:

#define T(...)   template< TYPENAMES(__VA_OPT__(,) __VA_ARGS__,3,2,1,0)(__VA_ARGS__) >
user17732522
  • 53,019
  • 2
  • 56
  • 105