如何在 C++ 中重载运算符 ->*

发布于 2024-10-24 18:03:13 字数 812 浏览 6 评论 0原文

有没有办法重载 ->* 以便与类似智能指针的对象一起使用?以下是我想做的事情。为简单起见,我没有使用模板(一旦我让它适用于单个固定类,我就会开始使用模板)。我可以让它与指向数据成员的指针一起工作,但我似乎无法正确地处理指向成员函数的指针。目前,我愿意接受仅适用于成员函数(而不适用于数据成员)的重载。我什至愿意满足于只接受指向具有单个固定原型的成员函数的指针(例如void func())的重载。

struct MyObject
{
   void MyMethod() {}
};

struct MySmartPtr {
   MyObject *p;

   // What should the prototype and function body be?
   // ??? operator->*(????) { ???? }
};

void MyFunc()
{
   MyObject obj;
   MySmartPtr obj_ptr;
   obj_ptr.p = &obj;
   void (MyObject::* member_func_ptr)() = &MyObject::MyMethod;

   // Now call obj.MyMethod() through the "smart pointer"
   (obj_ptr->*member_func_ptr)();
}

请不要向我提供解决方法(例如,重载 * 并执行 (*obj_ptr.*member_func_ptr)())。我希望 ->* 按照代码片段中的指示工作。

Is there a way to overload ->* for use with a smart-pointer-like object? Below is what I would like to do. For simplicity I'm not using templates (I'll get to that once I have it working for a single fixed class). I can get it to work with pointers to data members, but I can't seem to get it right for pointers to member functions. For the time being, I'm willing to settle for an overload that only works for member functions (and not for data members). I'm even willing to settle for an overload that only accepts pointers to member functions with a single fixed prototype (such as void func()).

struct MyObject
{
   void MyMethod() {}
};

struct MySmartPtr {
   MyObject *p;

   // What should the prototype and function body be?
   // ??? operator->*(????) { ???? }
};

void MyFunc()
{
   MyObject obj;
   MySmartPtr obj_ptr;
   obj_ptr.p = &obj;
   void (MyObject::* member_func_ptr)() = &MyObject::MyMethod;

   // Now call obj.MyMethod() through the "smart pointer"
   (obj_ptr->*member_func_ptr)();
}

Please don't offer me workarounds (e.g., overload * and do (*obj_ptr.*member_func_ptr)()). I want ->* to work as indicated in the code snippet.

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

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

发布评论

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

评论(3

鹤仙姿 2024-10-31 18:03:13

请参阅 Scott Meyers 的这篇文章。它很旧,但我所知道的唯一讨论重载 ->* 的资源。

请注意,标准库的迭代器和智能指针类型不会重载 ->*。我不知道原因,但我怀疑这是因为该运算符很少使用,实施起来很麻烦,而且很容易解决它。无论如何,由于标准库不支持它,因此您的用户也不会期望它能够工作。

Have a look at this article by Scott Meyers. It's quite old, but the only resource discussing overloading ->* that I know of.

Note that the standard library's iterator and smart pointer types don't overload ->*. I don't know the reasons, but I suspect it's because that operator rarely ever used, is a lot of hassle to implement, and it's easy to work around it. Anyway, since the standard library doesn't support it, your users won't expect it to work either.

送舟行 2024-10-31 18:03:13

http://codepad.org/yl3Ghwab

#include <stdio.h>

struct OBJ {
  typedef void (OBJ::*Met)(void);
  void met( void ) {
    printf( "Method call!\n" );
  }
};

struct POBJ {
  OBJ* p;
  typedef void (*fun)(void);
  static void nop( void ) {}
  fun operator->*( OBJ::Met m ) {
    printf( "operator ->* !\n" );
//    return fun(p->*m); // works in gcc
    (p->*m)();
    return nop;
  }
};

int main( void ) {
  OBJ obj;
  OBJ* pobj = &obj;
  POBJ p; p.p = &obj;
  OBJ::Met met = &OBJ::met;
  (pobj->*met)();
  (p->*met)();
}

请参阅http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B 用于原型

http://codepad.org/yl3Ghwab

#include <stdio.h>

struct OBJ {
  typedef void (OBJ::*Met)(void);
  void met( void ) {
    printf( "Method call!\n" );
  }
};

struct POBJ {
  OBJ* p;
  typedef void (*fun)(void);
  static void nop( void ) {}
  fun operator->*( OBJ::Met m ) {
    printf( "operator ->* !\n" );
//    return fun(p->*m); // works in gcc
    (p->*m)();
    return nop;
  }
};

int main( void ) {
  OBJ obj;
  OBJ* pobj = &obj;
  POBJ p; p.p = &obj;
  OBJ::Met met = &OBJ::met;
  (pobj->*met)();
  (p->*met)();
}

See http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B for prototypes

小伙你站住 2024-10-31 18:03:13

我将尝试使用 C++0x:可变参数模板、绑定和函数。我想应该可以将其移植到 boost:

#include <iostream>                                                             
#include <functional>                                                           

struct S
{       
  void f()
  {
    std::cout << __PRETTY_FUNCTION__ << std::endl;
  }
};

template<class C>
struct PMFSmartPtr
{
  C *p;
  template<typename C1, typename R, typename... P>
  std::function<R(P...)> operator->*(R (C1::*pmf)(P...))
  {
    std::cout << __PRETTY_FUNCTION__ << std::endl;
    return(std::function<R(P...)>(std::bind(pmf, p)));
  }
};

int main()
{
  PMFSmartPtr<S> x;
  void (S::*pmf)() = &S::f;
  (x->*pmf)();
  return(0);
}

在 g++ 4.4.4 上尝试过,并且适用于不带任何参数的函数,因为 1 个参数成员函数编译失败,但我不知道这是我的错还是编译器或 libstdc++ 问题。 ..

I'll give it a shot with C++0x: variadic templates, bind and function. I guess it should be possible to port it to boost:

#include <iostream>                                                             
#include <functional>                                                           

struct S
{       
  void f()
  {
    std::cout << __PRETTY_FUNCTION__ << std::endl;
  }
};

template<class C>
struct PMFSmartPtr
{
  C *p;
  template<typename C1, typename R, typename... P>
  std::function<R(P...)> operator->*(R (C1::*pmf)(P...))
  {
    std::cout << __PRETTY_FUNCTION__ << std::endl;
    return(std::function<R(P...)>(std::bind(pmf, p)));
  }
};

int main()
{
  PMFSmartPtr<S> x;
  void (S::*pmf)() = &S::f;
  (x->*pmf)();
  return(0);
}

Tried on g++ 4.4.4 and works for functions not taking any arguments, for 1 argument member function compilation fails but I do not know if this is my fault or compiler or libstdc++ issue...

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