我在哪里可以找到,或者如何创建一个优雅的 C++ 成员函数模板包装机制无需报告提升?

发布于 2024-07-25 02:37:49 字数 941 浏览 8 评论 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")
  );

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

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):

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

剧终人散尽 2024-08-01 02:37:49

我相信您需要采取一种特征方法,其中最常见的库是 boost ,但是如果您想避免 boost ,那么如果您将实现的范围限制为仅指向成员函数的指针以及您需要的特征(现代 C++ 设计 是一本解释该理论的好书)。 以下是我如何使用 boost 的 function_traits 和 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 */ };

请参阅 这个这个

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.

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:

#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 */ };

See this and this

岁月蹉跎了容颜 2024-08-01 02:37:49

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文