0

我希望能够在成员函数上模板化一个类,而无需重复成员函数的参数——即自动派生它们。如果我根据函数需要多少参数来命名类,我知道该怎么做,但我也想派生它。

像这样的东西,虽然这不起作用(至少在我的目标编译器 MSVC 2008 sp1 中):

class Foo {
  void func0();
  int func2(char *, float);
};

template<typename T> class Wrapper;

// specialize for zero-argument void func
template<typename Host, void (Host::*Func)()> class Wrapper<Func> : public Base {
  ... specialization goes here ...
};

// specialize for two-argument value func
template<typename Host, typename Ret, typename Arg0, typename Arg1, Ret (Host::*Func)(Arg0, Arg1)> class Wrapper<Func> : public Base {
  ... specialization goes here ...
};

通过“Base”,我可以多态地处理这些。最后,我想用它来为脚本语言创建一个简单的包装语法:

WrapClass<Bar> wrap(
  MemberFunction<&Bar::func0>("func0") +
  MemberFunction<&Bar::func2>("func2")
  );

但是,这不起作用:专业化语法是错误的,因为您无法将函数指针匹配到类型名参数。

4

2 回答 2

1

C++ 标准库提供mem_fun_ref了您想要的工作方式,尽管它仅适用于零元和一元函数。当然,您可以使用具有所有参数的结构作为您的一个参数。

于 2009-06-13T22:54:01.967 回答
1

我相信您需要采用特征方法,其中最常见的库是 boost's,但如果您想避免 boost,如果您将实现范围限制为仅指向成员函数的指针和您需要的那些特征(现代 C++ 设计是一本解释理论的好书)。下面是我如何使用 boost 的 function_traits 和 enable_if 来实现的。

您可以使用通用模板参数 enable_if 它作为函数指针,然后使用函数类型(或类型特征)提取您需要的信息:

#include <boost/function_types/function_arity.hpp>
#include <boost/function_types/is_member_pointer.hpp>

template<typename T, class Enable = void> class Wrapper;

/* other specializations... */

// For member functions:
template <class T>
class Wrapper<T, typename enable_if<is_member_pointer<T> >::type>
{ /* function_arity<T>::value has the number of arguments */ };

看到这个这个

于 2009-06-14T01:17:38.910 回答