If what you want is to remove the redundancy of the parameter names in the declaration (appearing once in the declaration list with their types, and once in the call list just as names), you can do this by supplying the names and the types as two separate lists, and just zipping them together with an appropriate two-parameter map macro.
Assuming the above is accurate, it looks like the actual parameter names aren't too important either, so you can lighten up your declaration further by predefining a list of dummy names, and leaving it out of the visible part of the declaration:
#define NARGS(...) NARGS_(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
#define NARGS_(_10, _9, _8, _7, _6, _5, _4, _3, _2, _1, N, ...) N
#define CAT(A, B) CAT_(A, B)
#define CAT_(A, B) A##B
#define ID(...) __VA_ARGS__
#define APPEND(L, E) ID(L),E
#define FIRST(A, ...) A
#define REST(A, ...) __VA_ARGS__
#define ZIP(F, L1, L2) CAT(ZIP_, ID(NARGS L1))(F, L1, L2)
#define ZIP_4(F, L1, L2) F(ID(FIRST L1), ID(FIRST L2)), ZIP_3(F, (ID(REST L1)), (ID(REST L2)))
#define ZIP_3(F, L1, L2) F(ID(FIRST L1), ID(FIRST L2)), ZIP_2(F, (ID(REST L1)), (ID(REST L2)))
#define ZIP_2(F, L1, L2) F(ID(FIRST L1), ID(FIRST L2)), ZIP_1(F, (ID(REST L1)), (ID(REST L2)))
#define ZIP_1(F, L1, L2) F(ID(FIRST L1), ID(FIRST L2))
#define ZIP_0(F, L1, L2)
#define GENSYMS (_0, _1, _2, _3, _4, _5, _6, _7, _8, _9)
#define runtime_subclass_method(Superclass,rtype,method,args)
rtype method(ZIP(EMIT_DECL, args, GENSYMS)) {
if( table.count(#method) == 0 ) return Superclass::method(ZIP(EMIT_CALL, args, GENSYMS));
return table.at(#method)(this, ID(ZIP(EMIT_CALL, args, GENSYMS)));
}
#define EMIT_DECL(T, N) T N
#define EMIT_CALL(T, N) N
runtime_subclass_method(Superclass,int,doSomething,(int,int))
Most of this example is utility stuff (such as CAT
). Expanding ZIP
, NARGS
and GENSYMS
to accept more arguments (four is a little small to be practical) should be trivial.
The method declaration just accepts a list of argument types, zips them together with names from a predefined list for the declaration, and just zips the length with the names to generate a call list.