Template parameter - function pointer with variadic arguments

馋奶兔 提交于 2019-12-09 04:51:34

问题


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 are bit ugly. In fact I don't know the number of arguments. Sounds like a work for variadic templates. Unfortunately I can't 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{}

Nor this:

template class C;

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

Do I want too much?


回答1:


You could 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




回答2:


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{};

should 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> {
};

like that.



来源:https://stackoverflow.com/questions/36549237/template-parameter-function-pointer-with-variadic-arguments

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!