Figure out why member function pointer doesn't work?

N

Nephi Immortal

Please look at my code below. You may notice operator->* with
comments. Figure out why it does not make any sense.

struct data;
typedef void ( data::*pGo )();

struct data {
char x;
char y;
pGo Go;

void Run() {
}
};

struct storage {
data *pData;

data *operator->() {
return pData;
}

storage &operator->*( pGo p ) {
( pData->*p )();
return *this;
}
};

int main()
{
data d; storage s;
s.pData = &d;
s->x = 1; s->y = 2; s->Go = &data::Run;

( d.* d.Go )(); // OK
( d.* s->Go )(); // OK

s.operator->*( s->Go ); // ??? Works fine
s->*( s->Go ); // ??? Works fine

( s->* s->Go )(); // Should be, but does not work!

return 0;
}
 
V

Victor Bazarov

Please look at my code below. You may notice operator->* with
comments. Figure out why it does not make any sense.

struct data;
typedef void ( data::*pGo )();

struct data {
char x;
char y;
pGo Go;

void Run() {
}
};

struct storage {
data *pData;

data *operator->() {
return pData;
}

storage&operator->*( pGo p ) {
( pData->*p )();
return *this;
}
};

int main()
{
data d; storage s;
s.pData =&d;
s->x = 1; s->y = 2; s->Go =&data::Run;

( d.* d.Go )(); // OK
( d.* s->Go )(); // OK

s.operator->*( s->Go ); // ??? Works fine
s->*( s->Go ); // ??? Works fine

( s->* s->Go )(); // Should be, but does not work!

What do you mean by "does not work"? Does it compile? If not, what's
the error message, what in it is unclear? If it does compile, do you
get an error when running?

Have you checked operator precedence? Can you place the parentheses in
the last expression to indicate how you think it should be evaluated?
Does it "work" after that? What's different (if anything) when you add
parentheses?
return 0;
}

V
 
N

Nephi Immortal

What do you mean by "does not work"?  Does it compile?  If not, what's
the error message, what in it is unclear?  If it does compile, do you
get an error when running?

Have you checked operator precedence?  Can you place the parentheses in
the last expression to indicate how you think it should be evaluated?
Does it "work" after that?  What's different (if anything) when you add
parentheses?

Victor,

You asked the same questions. I searched using google operator->*
across websites. There are a lot of operator->, but nothing showed
operator->*. There is no book mentioned it either.
I can say operator->* is rarely used. Please do a favor for me. Do
your homework to do research? Okay? If you succeed, the information
should be added to the book. You will be author as C++ book writer.
 
J

James Kanze

Please look at my code below. You may notice operator->* with
comments. Figure out why it does not make any sense.
struct data;
typedef void ( data::*pGo )();
struct data {
char x;
char y;
pGo Go;

void Run() {
}
};
struct storage {
data *pData;
data *operator->() {
return pData;
}
storage &operator->*( pGo p ) {

Here you define an operator->* which takes a storage and a
data::*pGo, and returns a storage. Why? What are you trying to
achieve.
( pData->*p )();
return *this;
}
};
int main()
{
data d; storage s;
s.pData = &d;
s->x = 1; s->y = 2; s->Go = &data::Run;
( d.* d.Go )(); // OK
( d.* s->Go )(); // OK
s.operator->*( s->Go ); // ??? Works fine
s->*( s->Go ); // ??? Works fine
( s->* s->Go )(); // Should be, but does not work!

s->*s->Go returns a storage&. You then try to call it as a
function. Since storage has no overloaded operator(), it fails.
What do you expect?
 
N

Nephi Immortal

Here you define an operator->* which takes a storage and a
data::*pGo, and returns a storage.  Why?  What are you trying to
achieve.


s->*s->Go returns a storage&.  You then try to call it as a
function.  Since storage has no overloaded operator(), it fails.
What do you expect?

James,

Do you know how to implement operator->* like I wrote operator->?
Operator->* and operator-> are very similar. Why can’t I use operator-
 
S

SG

Operator->* and operator-> are very similar.  Why can’t I use
operator->* to call struct data’s member function to pointer?

First of all, you need to recognize that the precedence of operator->
is higher than of the operator->*:

x->y->z is grouped like this: (x->y)->z

while

x->*y->z is grouped like this: x->*(y->z)

Secondly, what you are trying to do cannot work without a proxy
callable object. In order to make

(x->*y)();

work your operator->* function would need to return something that is
callable. Unfortunately, the result of ptr->*pmemfun where ptr is a
raw pointer and pmemfun is a member function pointer can only be used
as operand for the function call operator. You cannot return the
result of ptr->*pmemfun from a function and delay the function call
this way. C++ does not allow this.

If you want to support operator->* to be able to invoke member
functions you could try somehting like this:

struct bound_data_memfun {
data* ptr;
pGo pmemfun;
void operator()() const {return (ptr->*pmemfun)();}
// ^^^^^^^^^^^^^
// can only be used in combinaton with the function call
// operator.
};

struct storage {
...
bound_data_memfun operator->*(pGo pmemfun)
{
bound_data_memfun result = {pData,pmemfun};
return result;
}
...
};

IMHO it's not worth the hassle, though. None of the popular smart
pointer classes overload the operator->* and there is no harm in that.
Simply write

((*x).*y)();

and be done.

SG
 
S

SG

First of all, you need to recognize that the precedence of operator->
is higher than of the operator->*:

  x->y->z   is grouped like this:  (x->y)->z

while

  x->*y->z  is grouped like this:  x->*(y->z)

the relevant cases here are actually

x->y() is equiv to (x->y)()
x->*y() is equiv to x->*(y()) AND NOT to (x->*y)()

Operators -> and () form postfix expression while ->* and .* are
pointer-to-member operators with a lower precedence. Also:

" 5.5 Pointer-to-member operators [expr.mptr.oper]
[...]
6 If the result of .* or ->* is a function, then that result can
only be used as operand for the function call operator (). "

SG
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,053
Latest member
BrodieSola

Latest Threads

Top