Template parameter - function pointer with variable arguments

I know I can do this:

template<typename T, typename Ret, typename A1, typename A2, Ret(T::*F)(A1, A2)> class C{} 

But, as you can see, this A1 and A2 little ugly. In fact, I do not know the number of arguments. Sounds like work for variable templates. Unfortunately, I cannot do this:

 // doesn't work - parameter pack must appear at the end of the template parameter list template<typename T, typename Ret, typename... Args, Ret(T::*F)(Args...)> class C{} 

And this:

class C template;

 // doesn't work - wrong syntax template<typename T, typename F, typename Ret, typename... Args> class Delegate2<Ret(T::*F)(Args...)>{} 

I want too much?

+5
source share
2 answers

You can do the following:

 template<typename T, T> struct C; template<typename T, typename R, typename ...Args, R (T::*F)(Args...)> struct C<R (T::*)(Args...), F> { R operator()(T &obj, Args &&... args) { return (obj.*F)(std::forward<Args>(args)...); } }; 

and then in your program:

 struct A { int foo(int i) { return i; } }; int main() { C<int(A::*)(int), &A::foo> c; A a; std::cout << c(a, 42) << std::endl; } 

Live demo

+4
source
 template<class T>struct tag{using type=T;}; template<class Tag>using type=typename Tag::type; template<class T, class Sig> struct member_function_pointer; template<class T, class Sig> using member_function_pointer_t=type<member_function_pointer<T,Sig>>; template<class T, class R, class...Args> struct member_function_pointer<T, R(Args...)>: tag<R(T::*)(Args...)> {}; 

then

 template<class T, class Sig, member_function_pointer_t<T,Sig> mf> class C{}; 

gotta do the trick. If you need access to Args... you can specialize.

 template<class T, class Sig, member_function_pointer_t<T,Sig> mf> class C; template<class T, class R, class...Args, member_function_pointer_t<T,R(Args...)> mf> class C<T, R(Args...), mf> { }; 

.

+4
source

Source: https://habr.com/ru/post/1246872/


All Articles