Can this template syntax be improved?

I have this template method:

template <class SomeLhs, class SomeRhs, ResultType (SomeLhs::*callback)(SomeRhs&)> void Add() { struct Local { static ResultType Trampoline(BaseLhs& lhs, BaseRhs& rhs) { return (static_cast<SomeLhs&>(lhs).*callback)(static_cast<SomeRhs&>(rhs)); } }; _back_end.template Add<SomeLhs,SomeRhs>(&Local::Trampoline); } 

Currently, I call it as follows:

 tracker.Add<Quad, Multi, &Quad::track>(); tracker.Add<Quad, Singl, &Quad::track>(); tracker.Add<Sext, Multi, &Sext::track>(); ... 

It works fine, but I don't like repeating the name of the SomeLhs class SomeLhs . Is there any way to avoid this?

For people who may have learned this: yes, this is related to Alexandrescu's BasicFastDispatcher, in particular I am writing the front end for working with member functions.

+7
c ++ methods c ++ 11 templates
source share
1 answer

I do not think that this can not be improved especially, which is sad, since I would like to find a way to do this.

Template type inference is only possible for function template arguments, and you need to pass a non-type function pointer at compile time so that it can be considered as a name, not a variable number. This means that all arguments must be specified.

i.e. You can do it:

 template <class SomeLhs, class SomeRhs> void Add(ResultType (SomeLhs::*callback)(SomeRhs&)) { ... } // nice syntax: tracker.Add(&Sext::track); // But ugly for overloaded functions, a cast is needed. // ps not sure this is exactly the right syntax without compiling it. tracker.Add((ResultType (Quad::*)(Multi&) &Quad::track); 

But then you have an actual pointer, which subsequently cannot be used as a template parameter.

The only thing I think you can do is use a macro, although it can be argued that it really improves the syntax here. I would say that this probably adds an unnecessary level of obfuscation.

eg.

 #define TMFN_ARGS(C, M, P1) C, P1, &C::M tracker.Add<TMFN_ARGS(Quad, track, Multi)>(); 

EDIT:

However, if the function name is Always 'track', you can do something in the following lines:

 template <typename C, typename P1> void AddTrack() { Add<C, P1, &C::track>(); } tracker.AddTrack<Quad, Multi>(); 
+3
source share

All Articles