S
I have done it!
I have tried to do it for 3 months! Then I given up and wrote here that I cannot solve the problem. While I was writing something changed in my mind, and I came up to the solution in 2 hours. Here it is: universal runtime-to-compile-time dispatcher:
template<class F, class A, class ...B> struct Dispatch {
template<class ...C> static inline decltype(&F::template f<C..., A>) f(std::size_t const i) {
assert( i <= sizeof...(B) );
static constexpr decltype(&F::template f<C..., A>) table[] {
&F::template f<C..., A>, &F::template f<C..., B>...
};
return table[i];
}
};
struct Test1 {
template<class A> static void f(int b) {
std::cout << typeid(A).name() << ", " << b << std::endl;
}
};
struct Test2 {
template<class A, class B> static void f(int c) {
std::cout << typeid(A).name() << ", " << typeid(B).name() << ", " << c << std::endl;
}
};
#define LIST int, float, double
int main(void) {
Dispatch<Test1, LIST>::f(1)(2); //«float, 2»
Dispatch<Dispatch<Test2, LIST>, LIST>::f(1)(2)(3); //«float, double, 3»
return 0;
}
Thanks!