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); });
Comments
Post a Comment