Hi, 2010/7/28 Hite, Christopher <christopher.h...@partner.commerzbank.com>: >> Generally without knowing the compiler version you are using >> it is hard to tell. > I'll use whatever's best. Right now I'm still on 4.4.3. I'll probably > upgrade soon to 4.5. > >> The same is true without a complete compilable testcase. > I didn't want to make a test case that depends on boost::mpl. How's > this: > > struct DecodeContext; > > struct M1{ > static const int id=1; > static void decode(DecodeContext& ){} > }; > > struct M2{ > static const int id=2; > static void decode(DecodeContext& ){} > }; > > struct M3{ > static const int id=3; > static void decode(DecodeContext& ){} > }; > > > template <int> struct ListMember; > > template <> struct ListMember<1>{ typedef M1 type; }; > template <> struct ListMember<2>{ typedef M2 type; }; > template <> struct ListMember<3>{ typedef M3 type; }; > > template<int i> > void foo(int id, DecodeContext& dc) { > typedef typename ListMember<i>::type M; > if(M::id==id) > M::decode(dc); > else > foo<i-1>(id,dc); > } > > template<> > void foo<0>(int id, DecodeContext& dc) {} > > > > int main(){ > DecodeContext& dc= *(DecodeContext*)0;// junk for now > int id=2; //sometime runtime dependent > foo<3>(id,dc); > return 0; > } > > >> You can use the flatten attribute to tell the compiler to inline all >> calls in a given function, like >> >> void __attribute__((flatten)) foo(void) >> { >> ... >> decode1(); >> ... >> } > > That would cause decode1() to be inlined, which might not be what you > want. > > Hmm maybe I could rewrite things so the switch case returns a function > pointer. I'm guessing that would make things slower though. >
Or you could just initialize static array of pointers, like that (please note, that I never compiled code below): typedef void (*pfn) (DeclContext&); tempate <int I> struct InitDispatchHelper { static void init(std::tr1::array<pfn,N>& a) { a[I-1] = ListMemeber<I-1>::foo; InitPointersHelper<I-1>::init(a); } }; // End recursion template<> struct InitDispatchHelper { static void init(std::tr1::array<pfn,N>& a) { /*does nothing */ } }; // Dispatch table; template <int N> struct DispatchFoo : std::tr1::array<pfn, N> { DispatchFoo() : std::tr1::array<pfn, N>() { InitDispatchHelper<N>::init(*this); } }; then your call would look like: static const int X = /* your maximal I in ListMembers meta-class */ void call_foo(int i, DeclContext& c) { static const DispatchFoo<X> foo_dispatch; foo_dispatch[i] (c); } Bonus points for benchmarking both solutions and making it policy class choosing between those two solutions depending on X. Good luck, Piotr