c++ - passing member-function as argument to function-template -


consider 3 ways implement routine in c++: through functors, member functions, , non-member functions. example,

#include <iostream> #include <string>  using std::cout; using std::endl; using std::string;  class foo { public:   void operator() (string word)         // first: functor   {     cout << word << endl;   }    void m_function(string word)          // second: member-function   {     cout << word << endl;   } } functor;   void function(string word)              // third: non-member function {   cout << word << endl; } 

now consider template-function call 3 functions above:

template<class t> void eval(t fun) {   fun("using external function"); } 

what proper way call foo::m_function through eval? tried:

functor("normal call");               // ok: call ‘void foo::operator()(string)‘ eval(functor);                        // ok: instantiation of ‘void eval(t) [with t = foo]’  function("normal call");              // ok: call ‘void function(string)’ eval(function);                       // ok: instantiation of ‘void eval(t) [with t = void (*)(string)]’  functor.m_function("normal call");    // ok: call member-function ‘foo::m_function(string)’ eval(functor.m_function);             // error: cannot convert ‘foo::m_function’ type                                       //        ‘void (foo::)(std::string) {aka void (foo::)(string)}’                                       //        type ‘void (foo::*)(std::basic_string<char>)’                                       // in instantiation of ‘void eval(t) [with t = void (foo::*)(string)]’:                                       // error: must use ‘.*’ or ‘->*’ call pointer-to-member function in ‘fun (...)’, e.g. ‘(... ->* fun) (...)’ 

a pointer member function , pointer function 2 different beasts. former takes implicit first argument, this pointer, or in other words, pointer instance on member function invoked on.

typically, in order able pass member function callable object, bind instance on invoked on, , use placeholders indicate arguments passed callable later. in case

eval(std::bind(&foo::m_function, &functor, std::placeholders::_1)); 

the first argument bind above pointer member function want invoke, , second pointer foo instance on want invoke m_function. last 1 placeholder indicates first argument passed callable created bind should used when calling member function.

another way pass lambda expression eval takes char const * (or std::string const&) argument , calls member function.

eval([](char const *c) { functor.m_function(c); }); 

live demo


Comments

Popular posts from this blog

python - TypeError: start must be a integer -

c# - DevExpress RepositoryItemComboBox BackColor property ignored -

django - Creating multiple model instances in DRF3 -