This question is a follow-on from https://stackoverflow.com/a/5365786/383306.
#define _DEFINE_REF_INTERNAL2(id, ...)
#define _DEFINE_REF_INTERNAL1(id)
#define _VA_NARGS_2_IMPL(_1, _2, N, ...) N
#define _VA_NARGS_2(...) _VA_NARGS_2_IMPL(__VA_ARGS__, 2, 1)
#define _DEFINE_REF_IMPL2(count, ...) _DEFINE_REF_INTERNAL ## count (__VA_ARGS__)
#define _DEFINE_REF_IMPL(count, ...) _DEFINE_REF_IMPL2(count, __VA_ARGS__)
#define DEFINE_REF(...) _DEFINE_REF_IMPL(_VA_NARGS_2(__VA_ARGS__), __VA_ARGS__)
DEFINE_REF(MyClass, typename... Args, Args...);
// error: ‘_DEFINE_REF_INTERNALArgs’ does not name a type
DEFINE_REF(MyClass, typename T, T); // this is OK
How do I make the macro trick work when passing ellipsis as part of an argument?
The problem isn’t with the ellipsis. The problem is that you are passing three arguments in
__VA_ARGS__toDEFINE_REF, but_VA_NARGS_2only handles up to two arguments.Once you fix that, the program (I believe) exhibits the desired behavior. gcc 4.7.2 and Clang 3.2 both transform this:
into this:
(Also note that names beginning with an underscore followed by a capital letter are reserved for the implementation. You may not use such names for your own macros.)
If you are targeting Visual C++, you will need a barrel of indirection to make this work, as it does not correctly replace macros before rescanning in all cases. The following will work with Visual C++ (This solution is also conforming and works with gcc and Clang as well):