home bbs files messages ]

Forums before death by AOL, social media and spammers... "We can't have nice things"

   comp.lang.c++.moderated      Moderated discussion of C++ superhackery      33,346 messages   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]

   Message 32,895 of 33,346   
   SG to Jerry   
   Re: currying pointer to member functions   
   07 Mar 13 05:29:39   
   
   eadf49a3   
   d4526246   
   From: s.gesemann@googlemail.com   
      
   On Mar 6, 12:20 am, Jerry wrote:   
   > I can make this work:   
   >   
   >   struct a   
   >   {   
   >     int b;   
   >     int c() {return b+1;}   
   >     int d(int x) {return b+x;}   
   >   };   
   >   
   >   int main()   
   >   {   
   >     a m = { 1 }, n = { 2 };   
   >     a *ps = &m;   
   >     int (a::*pf)() = &a::c;   
   >     std::cout << (ps->*pf)() << std::endl;   
   >     return 0;   
   >   }   
   >   
   > And it runs the function and everything works.  But what I want to   
   > do is curry the function so that I can store (ps->*pf) and then   
   > later execute it.  So what is the type of &(ps->*pf) ?   
      
   The type of (ps->*pf) is int() but the C++ standard says that the only   
   thing you can do with it is to actually call the function via the   
   function call operator. That makes the expression &(ps->*pf) illegal.   
      
   > I make a class:   
   >   
   >     template   
   >     class ArrowStarVoidFunc   
   >     {   
   >     private:   
   >         R(O::*fptr)();   
   >     public:   
   >         ArrowStarVoidFunc(R(O::*f)()) : fptr(f) {}   
   >         R operator()(O* o) const { return (o->*fptr)(); }   
   >     };   
   >   
   >     template   
   >     ArrowStarVoidFunc operator->*(R(O::*f)())   
   >         { return ArrowStarVoidFunc(f); }   
   >   
   > Which seems to work fine except it also executes the function.   
      
   This looks similar to what std::mem_fun already does.   
      
   > What I   
   > want to do is the following, but what goes where the ???? is:   
   >   
   >     template   
   >     class ArrowStarVoidFunc   
   >     {   
   >     private:   
   >         R(O::*fptr)();   
   >     public:   
   >         ArrowStarVoidFunc(R(O::*f)()) : fptr(f) {}   
   >         ???? operator()(O* o) const { return &(o->*fptr); }   
   >     };   
   >   
   > Oh, and to make all this more interesting (i.e. complicated) I am   
   > working with a compiler that is more than 10 years old and is only   
   > compatible with C++98 - if I could a newer compiler I wouldn't be   
   > asking this!   
      
   You can return a function object of a custom type:   
      
        template   
        class bound_mem_fun   
        {   
        public:   
            bound_mem_fun(R (O::*f)(), O* o)   
                : f(f), o(o) {}   
            R operator()() const   
            { return (o->*f)(); }   
        private:   
            R (O::*f)();   
            O* o;   
        };   
      
   It stores the function pointer as well as the object pointer. The C+   
   +98 standard library is short on this kind of wrapper. It only   
   provides bind1st and bind2nd which take binary functors and return   
   unary functors.   
      
   In addition, C++11 offers a more general std::bind as well as lambda   
   expressions which would be of help here if you were not restricted to   
   C ++98. But maybe you can make use of Boost.Bind instead. It's kind of   
   the predecessor to std::bind:   
      
        O* o = ...;   
        R (O::*f) = ...;   
      
        boost::bind(f,o)  ();   
        ^^^^^^^^^^^^^^^^  ^^   
         yields nullary  invokes   
             functor      it   
      
      
   Cheers!   
   SG   
      
      
   --   
         [ See http://www.gotw.ca/resources/clcm.htm for info about ]   
         [ comp.lang.c++.moderated.    First time posters: Do this! ]   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]


(c) 1994,  bbs@darkrealms.ca