Figure out why member function pointer doesn't work?

Discussion in 'C++' started by Nephi Immortal, Apr 2, 2011.

  1. 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;
    }
     
    Nephi Immortal, Apr 2, 2011
    #1
    1. Advertising

  2. On 4/1/2011 9:15 PM, Nephi Immortal wrote:
    > 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
    --
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Apr 2, 2011
    #2
    1. Advertising

  3. Nephi Immortal

    Qi Guest

    On 2011-4-2 9:15, Nephi Immortal wrote:
    > ( s->* s->Go )();


    "( s->* s->Go )(); "
    ==
    (( s->* s)->Go )();

    So it won't compile.


    --
    WQ
     
    Qi, Apr 2, 2011
    #3
  4. On Apr 1, 9:55 pm, Victor Bazarov <> wrote:
    > On 4/1/2011 9:15 PM, Nephi Immortal wrote:
    >
    >
    >
    >
    >
    > >    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?


    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.


    >
    >
    >
    > >    return 0;
    > > }

    >
    > V
    > --
    > I do not respond to top-posted replies, please don't ask- Hide quoted text -
    >
    > - Show quoted text -
     
    Nephi Immortal, Apr 2, 2011
    #4
  5. Nephi Immortal

    James Kanze Guest

    On Apr 2, 2:15 am, Nephi Immortal <> wrote:
    > 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?

    > return 0;
    > }


    --
    James Kanze
     
    James Kanze, Apr 3, 2011
    #5
  6. On Apr 3, 11:54 am, James Kanze <> wrote:
    > On Apr 2, 2:15 am, Nephi Immortal <> wrote:
    >
    >
    >
    >
    >
    > > 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?
    >
    > >         return 0;
    > > }


    James,

    Do you know how to implement operator->* like I wrote operator->?
    Operator->* and operator-> are very similar. Why can’t I use operator-
    >* to call struct data’s member function to pointer?
     
    Nephi Immortal, Apr 5, 2011
    #6
  7. Nephi Immortal

    SG Guest

    On 5 Apr., 03:41, Nephi Immortal wrote:
    > 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
     
    SG, Apr 5, 2011
    #7
  8. Nephi Immortal

    SG Guest

    On 5 Apr., 09:22, SG wrote:
    > On 5 Apr., 03:41, Nephi Immortal wrote:
    >
    > > 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)


    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
     
    SG, Apr 5, 2011
    #8
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Rinus Luijmes
    Replies:
    1
    Views:
    1,165
    TopoGrafix
    Aug 3, 2005
  2. Fraser Ross
    Replies:
    4
    Views:
    1,068
    Fraser Ross
    Aug 14, 2004
  3. Mr. SweatyFinger
    Replies:
    2
    Views:
    2,077
    Smokey Grindel
    Dec 2, 2006
  4. Aaron Walker
    Replies:
    4
    Views:
    721
    Aaron Walker
    Oct 1, 2005
  5. somenath
    Replies:
    2
    Views:
    170
    somenath
    Aug 29, 2013
Loading...

Share This Page