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,419 of 33,346   
   =?ISO-8859-1?Q?Daniel_Kr=FCgler?= to All   
   Re: How to pass a function pointer to a    
   19 Jun 12 15:27:21   
   
   From: daniel.kruegler@googlemail.com   
      
   Am 15.06.2012 01:45, schrieb Jens Auer:   
   [..]   
   > What I need would be a generic way to call the function in   
   > a unified way regardless of it being a member or free   
   > function with first paramter A*, so I came up with the idea   
   > to use std::function.   
      
   Indeed you can solve your problem using std::function, Ulrich has   
   given a hint how to solve this by explaining the mechanism and   
   constraints of the deduction process. The trick is to prevent the   
   attempt to deduce the concrete std::function instance by taking   
   advantage of non-deduced context. Just define your function templates   
   like so   
      
   template   
   struct identity { typedef T type; };   
      
   template   
   void call(typename identity>::type func, T x)   
   {   
       A a;   
       func(&a,x);   
   }   
      
   template   
   void call2(typename identity>::type func, T x)   
   {   
       func(x);   
   }   
      
   and it should work. The construction typename identity::type   
   prevents any attempts to deduce blah (because this is generally not   
   possible).   
      
   > Is there something like std::call(f, x, y)?   
      
   There is not yet such a beast. I would like to have it added to the   
   Standard Library, it could replace the conceptual INVOKE "function"   
   from the Standard Library specification. For similarity reasons with   
   INVOKE I would suggest to name this function template std::invoke   
   instead of std::call, though. It is definitively implementable, I have   
   gone through that and it does not depend on std::function at all. You   
   can consider it as a general function template of the form that Ulrich   
   describes.   
      
   >> There are two parameters of the function which are used in deducing   
   >> the type of T. The second one gives an obvious 'int' as answer. The   
   >> first one however is not so clear, because the given type (function   
   >> pointer) is not actually the one in the function declaration   
   >> (std::function).  Instead, it first requires a conversion to the   
   >> argument type. However, in order to perform that conversion, you   
   >> first need to know the argument type, which again depends on the   
   >> template parameters. In other words, you have a chicken-and-egg   
   >> problem here, which is where compiler simply bails out and refuses   
   >> to guess.   
   >   
   > Why can't the compiler use the information available when computing   
   > the type for call(&A::memberF, 0)? As you said, the second paramter   
   > binds T to int and solves the problem, so in that special case the   
   > type-inference can work.   
      
   Well, it cannot work in the way you declared your call(2) templates,   
   because the deduction mechanism cannot deduct the template parameter T   
   for any std::function given some (arbitrary) type U that is just   
   *convertible* to some std::function. By means of the simple   
   technique shown above you can use your std::function-based approach by   
   disabling the deduction for the std::function function parameter.   
      
   HTH & Greetings from Bremen,   
      
   Daniel Krügler   
      
   --   
         [ 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