我在哪里可以找到,或者我如何创建一个优雅的C++成员函数模板包装机制而不用提升?
我希望能够在成员函数上模板化类,而不需要重复成员函数的参数 - 即,自动派生它们。 我知道如何做到这一点,如果我根据函数需要多少个参数命名类,但我也想得到。我在哪里可以找到,或者我如何创建一个优雅的C++成员函数模板包装机制而不用提升?
这样的事情,虽然这不工作(至少在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 ...
};
通过“基地”然后我就可以多态地对待这些。最后,我想用它来创建一个简单的包装语法的脚本语言:
WrapClass<Bar> wrap(
MemberFunction<&Bar::func0>("func0") +
MemberFunction<&Bar::func2>("func2")
);
然而,这并不工作:专业化的语法是错误的,因为你不能一个函数指针匹配到一个typename参数。
我相信你需要采取一种特质方法,其中最常用的库是boost,但是如果你想避免提升,如果你限制了范围,那么推出你自己并不是非常困难实现只是指向成员函数和你需要的特性(modern c++ design是解释理论的好书)。以下是我将如何使用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 */ };
C++标准库提供mem_fun_ref
哪种工作方式是你想要的,尽管它只适用于无限和一元函数。当然,你可以使用一个包含所有参数的结构作为你的一个参数。
可悲的是,我不能使用结构,因为这不能用于以简单的方式将脚本语言绑定到一堆现有类的用例。还是)感谢你的建议! – 2009-06-14 00:55:32
我没有提到“没有提升”的要求吗?我想我没有。 虽然我确实有这样的要求 - 对不起,我没有提到它。 但是,我会深入探讨boost头文件,看看他们做了什么,并模仿我需要的小子集。 我相信我最终不得不定义一个专用于arity的Wrapper内部模板。 – 2009-06-16 17:48:01