I want to be able to templatize a class on a member function without needing to repeat the arguments of the member function -- i e, derive them automatically. I know how to do this if I name the class based on how many arguments the function takes, but I want to derive that as well.
我希望能够在成员函数上模板化一个类而不需要重复成员函数的参数 - 即,自动导出它们。我知道如何根据函数所使用的参数来命名类,但我也希望得到它。
Something like this, although this doesn't work (at least in MSVC 2008 sp1, which is my target compiler):
像这样的东西,虽然这不起作用(至少在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 ...
};
Through "Base" I can then treat these polymorphically. In the end, I want to use this to create a simple wrapper syntax for a scripting language:
通过“基地”我可以对这些进行多态处理。最后,我想用它来为脚本语言创建一个简单的包装器语法:
WrapClass<Bar> wrap(
MemberFunction<&Bar::func0>("func0") +
MemberFunction<&Bar::func2>("func2")
);
However, that doesn't work: the specialization syntax is wrong, because you can't match a function pointer to a typename argument.
但是,这不起作用:专门化语法是错误的,因为您无法将函数指针与typename参数匹配。
2 个解决方案
#1
I believe you'll need to take a traits approach, the most common library of which is boost's, but if you wanted to avoid boost, it wouldn't be extremely difficult to roll your own if you limited the scope of the implementation to just pointer-to-member-functions and the traits on those you need (modern c++ design is a great book explaining the theory). Here's how I would do it with boost's function_traits and enable_if.
我相信你需要采取一种特质方法,其中最常见的库是boost,但是如果你想避免提升,如果你将实现的范围限制在仅仅是非常困难的话。指向成员函数的指针和你需要的特征(现代c ++设计是解释理论的好书)。这是我用boost的function_traits和enable_if来做的。
You could use a generic template argument, enable_if it for function pointers, then use function types (or type traits) to pull out out the information you need:
您可以使用通用模板参数,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 */ };
看到这个和这个
#2
The C++ standard library provides mem_fun_ref
which sort of works how you want, though it only works for nullary and unary functions. Of course, you can use a struct with all the parameters as your one argument.
C ++标准库提供了mem_fun_ref,它可以按照你想要的方式工作,尽管它只适用于nullary和unary函数。当然,您可以使用包含所有参数的结构作为您的一个参数。
#1
I believe you'll need to take a traits approach, the most common library of which is boost's, but if you wanted to avoid boost, it wouldn't be extremely difficult to roll your own if you limited the scope of the implementation to just pointer-to-member-functions and the traits on those you need (modern c++ design is a great book explaining the theory). Here's how I would do it with boost's function_traits and enable_if.
我相信你需要采取一种特质方法,其中最常见的库是boost,但是如果你想避免提升,如果你将实现的范围限制在仅仅是非常困难的话。指向成员函数的指针和你需要的特征(现代c ++设计是解释理论的好书)。这是我用boost的function_traits和enable_if来做的。
You could use a generic template argument, enable_if it for function pointers, then use function types (or type traits) to pull out out the information you need:
您可以使用通用模板参数,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 */ };
看到这个和这个
#2
The C++ standard library provides mem_fun_ref
which sort of works how you want, though it only works for nullary and unary functions. Of course, you can use a struct with all the parameters as your one argument.
C ++标准库提供了mem_fun_ref,它可以按照你想要的方式工作,尽管它只适用于nullary和unary函数。当然,您可以使用包含所有参数的结构作为您的一个参数。