C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

How to overload operator->*

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Tobias Güntner
Guest





PostPosted: Tue Jul 20, 2004 7:54 am    Post subject: How to overload operator->* Reply with quote



Hi!
I guess many people know how to overload operator-> (e.g. in a smart
pointer class), but how can one overload operator->* properly? I know it
has to return something that can be called like a function and I found a
small example at <http://www.briceg.com/ticpp/one/Chapter12.html#Heading362>
But how to implement a generic operator->*?

At first I tried

class Pointer
{
public:
int Work(int i) { return i + 1; }

template<typename PMF>
class FunctionObject
{
Pointer* ptr;
PMF pmem;
public:
FunctionObject(Pointer* wp, PMF pmf)
: ptr(wp), pmem(pmf) { }

template<class T>
operator T() const
{
return ptr->*pmem;
}
};

template<typename PMF>
FunctionObject<PMF> operator->*(PMF pmf) {
return FunctionObject<PMF>(this, pmf);
}
};

int main()
{
Pointer w;
int (Pointer::*pmf)(int) = &Pointer::Work;
// error: no match for call to
// `(Pointer::FunctionObject<int(Pointer::*)(int)>) (int)'
cout << (w->*pmf)(1) << endl;

return 0;
}

but it didn't work (I guess it would have worked if I provided a correct
conversion operator, but I don't know which type ptr->*pmem returns. I
wonder if it's possible to express this type in C++ at all...)

After that I tried the following:

class Pointer
{
public:
int Work(int i) { return i + 1; }

template<typename R, typename P1>
class FunctionObject1
{
Pointer* ptr;
R (Pointer::*pmem)(P1);
public:
FunctionObject1(Pointer* wp, R (Pointer::*pmf)(P1))
: ptr(wp), pmem(pmf) { }

R operator()(P1 p1)
{
return (ptr->*pmem)(p1);
}
};

template<typename R, typename P1>
FunctionObject1<R,P1> operator->*(R (Pointer::*pmf)(P1))
{
return FunctionObject1<R,P1>(this, pmf);
}
};

int main()
{
Pointer w;
int (Pointer::*pmf)(int) = &Pointer::Work;
cout << (w->*pmf)(1) << endl;

return 0;
}

This worked (g++ 3.3.1), but a) I don't really feel like writing dozens
of operator()s with 0..n parameters and b) I don't want too many copies
of an object if it's passed by value (although it would probably be
possible to solve the latter problem and use a 'const T&' at that places
using some sort of traits class).
Is there a better/more elegant solution to this problem?

Regards,
Tobias

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Maxim Yegorushkin
Guest





PostPosted: Tue Jul 20, 2004 6:27 pm    Post subject: Re: How to overload operator->* Reply with quote



Tobias GГјntner <fatbull (AT) web (DOT) de> wrote:

Quote:
I guess many people know how to overload operator-> (e.g. in a smart
pointer class), but how can one overload operator->* properly? I know it
has to return something that can be called like a function and I found a
small example at <http://www.briceg.com/ticpp/one/Chapter12.html#Heading362

For data members it returns a reference to the member.

struct some { int i_; } s, *ps = &s;
int some::*pi = &some::i_;
int &ri = ps->*pi;

Quote:
But how to implement a generic operator->*?

You can implement it using boost::function<> and boost::bind:

template<class T> struct smart_ptr {/*...*/};

// for one arg member functions
template<class T, class R, A0>
inline
function<R(A0)> operator->*(smart_ptr<T> const& p, R(T::*f)(A0))
{
struct invoker
{
static R invoke(smart_ptr<T> const& p, R(T::*f)(A0), A0 const& a0)
{
return (p.get()->*f)(a0);
}
};
return function<R()>(bind(&invoker::invoke, p, f, _1));
}

// add versions for N args, member functions, handle reference args

--
Maxim Yegorushkin

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Joe
Guest





PostPosted: Tue Jul 20, 2004 9:35 pm    Post subject: Re: How to overload operator->* Reply with quote




"> But how to implement a generic operator->*?
Quote:
: Do this! ]

Several years ago a read an article on the Dr. Dobbs web site about this
issue. You may want to search for it.




[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Tobias Güntner
Guest





PostPosted: Wed Jul 21, 2004 7:49 pm    Post subject: Re: How to overload operator->* Reply with quote

Maxim Yegorushkin wrote:
Quote:
For data members it returns a reference to the member.

struct some { int i_; } s, *ps = &s;
int some::*pi = &some::i_;
int &ri = ps->*pi;


Ah, of course... That's right. I totally forgot data members Wink Thanks.

Quote:

But how to implement a generic operator->*?


You can implement it using boost::function<> and boost::bind:

template<class T> struct smart_ptr {/*...*/};

// for one arg member functions
template<class T, class R, A0
inline
function*(smart_ptr<T> const& p, R(T::*f)(A0))
{
struct invoker
{
static R invoke(smart_ptr<T> const& p, R(T::*f)(A0), A0 const& a0)
{
return (p.get()->*f)(a0);
}
};
return function<R()>(bind(&invoker::invoke, p, f, _1));
}

// add versions for N args, member functions, handle reference args


Looks good.
I'll have a closer look at boost::function<>. Thanks again :)

Regards,
Tobias

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Tobias Güntner
Guest





PostPosted: Wed Jul 21, 2004 7:50 pm    Post subject: Re: How to overload operator->* Reply with quote

Joe wrote:

Quote:
Several years ago a read an article on the Dr. Dobbs web site about this
issue. You may want to search for it.

I do. I hope it's still online.


Regards,
Tobias

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.