Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to overload the ->* operator?

Tags:

c++

I tried this, and some variations on it:

template<class T>
class Ptr {
public:
    Ptr(T* ptr) : p(ptr) {}
    ~Ptr() { if(p) delete p; }

    template<class Method>
    Method operator ->* (Method method)
    {
        return p->*method;
    }

private:
    T *p;
};

class Foo {
public:
    void foo(int) {}
    int bar() { return 3; }
};

int main() {
    Ptr<Foo> p(new Foo());

    void (Foo::*method)(int) = &Foo::foo;
    int (Foo::*method2)() = &Foo::bar;

    (p->*method)(5);
    (p->*method2)();

    return 0;
}

But it doesn't work. The problem is that I don't really know what to expect as a parameter or what to return. The standard on this is incomprehensible to me, and since Google did not bring up anything helpful I guess I'm not alone.

Edit: Another try, with C++0x: http://ideone.com/lMlyB

like image 227
Fozi Avatar asked Apr 07 '11 20:04

Fozi


People also ask

How do you overload the operator?

To overload an operator, we use a special operator function. We define the function inside the class or structure whose objects/variables we want the overloaded operator to work with.

How do you overload pre increment operator?

You overload the prefix increment operator ++ with either a nonmember function operator that has one argument of class type or a reference to class type, or with a member function operator that has no arguments.

Can we overload -> operator CPP?

Class Member Access Operator (->) Overloading in C++ The class member access operator (->) can be overloaded but it is bit trickier. It is defined to give a class type a "pointer-like" behavior.

Can you overload scope resolution operator?

No. There are C++ operators that can't be overloaded. They include: :: -Scope resolution operator.


1 Answers

The return of operator->* represents a function in the process of being called, with the only missing parts being the parameters. Thus, you must return a functor that invokes the given function on the given object with the given parameters:

// PTMF = pointer to member function
template<class Obj>
struct PTMF_Object{
  typedef int (Obj::*ptmf)(double,std::string); // example signature

  PTMF_Object(Obj* obj, ptmf func)
    : obj_(obj)
    , func_(func)
  {}

  int operator()(double d, std::string str){
    return (obj_->*func_)(d,str);
  }

  Obj* obj_;
  ptmf func_;
};

template<class T>
struct SmartPtr{
  // ...

  PTMF_Object<T> operator->*(PTMF_Object<T>::ptmf func){
    return PTMF_Object<T>(p, func);
  }
  // ...
};

int main(){
  SmartPtr<Foo> pf(new Foo());
  typedef int (Foo::*Foo_ptmf)(double,std::string);
  Foo_ptmf method = &Foo::bar;

  (pf->*method)(5.4, "oh hi");
}

Edit2
Here is an excellent pdf from Scott Meyers on this very topic (it's the only good literature on overloading operator->*, even though it's from 1999).

Edit
Here is one, if your compiler supports variadic templates: http://ideone.com/B6kRF

like image 165
Xeo Avatar answered Sep 21 '22 14:09

Xeo