模板参数 - 带有可变参数的函数指针

Template parameter - function pointer with variadic arguments

我知道我能做到:

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

但是如您所见,A1A2 有点难看。事实上,我不知道参数的数量。听起来像是可变参数模板的工作。不幸的是我不能这样做:

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

也不是这个:

模板 class C;

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

我是不是想要太多了?

您可以执行以下操作:

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)...);
  }

};

然后在您的程序中:

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

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

然后

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

应该可以解决问题。如果您需要访问 Args...,您可以专攻。

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

就这样。