c++ - Invoking member of an object from another one by using `std::function` -
i'm trying create communication system between objects, in controller object keeps vector of member functions of other objects, , calls/invokes them when needed.
read several articles usage of std::function
, couldn't find 1 covers use case.
my code is:
#include <functional> #include <windows.h> class callable { }; class classa : public callable { public: double callthis(double x, int y) const { messageboxw(null, l"callthis() called.", l"in classa", mb_iconinformation); return x + y; } }; class classb : public callable { public: double callme(double x, int y) const { messageboxw(null, l"callme() called.", l"in classb", mb_iconinformation); return x + y; } }; class caller { public: void addsubscriber( const callable & objecttocall, const std::function<double(const callable &, double, int)> & subscriber) { subscribers.push_back(subscriber); objectstobecalled.push_back(objecttocall); } void callsubscribers() { (size_t i=0; i<subscribers.size(); i++) { subscribers[i](objectstobecalled[i], 1.0, 2); } } private: std::vector<std::function<double(const callable &, double, int)>> subscribers; std::vector<const callable &> objectstobecalled; }; int apientry wwinmain( _in_ hinstance hinstance, _in_opt_ hinstance hprevinstance, _in_ lptstr lpcmdline, _in_ int ncmdshow) { // ... classa objecta; classb objectb; caller objectcaller; objectcaller.addsubscriber(objecta, &classa::callthis); objectcaller.addsubscriber(objecta, &classb::callme); sleep(5000); objectcaller.callsubscribers(); // ... }
the strange that, when run code don't compiler errors in own code, errors stl files xmemory0
, vector
. errors are:
error 1 xmemory0 527 error c2528: 'pointer' : pointer reference illegal error 2 xmemory0 528 error c2528: 'const_pointer' : pointer reference illegal error 3 xmemory0 561 error c2535: 'const callable &(*std::allocator<_ty>::address(const callable &) throw() const)' : member function defined or declared error 4 xmemory0 599 error c2528: '_ptr' : pointer reference illegal error 5 xmemory0 604 error c2528: '_ptr' : pointer reference illegal error 6 xmemory0 700 error c2528: 'pointer' : pointer reference illegal error 7 xmemory0 701 error c2528: 'const_pointer' : pointer reference illegal error 8 xmemory0 824 error c2535: 'const callable &(*std::_wrap_alloc<_alloc>::address(const callable &) const)' : member function defined or declared error 9 xmemory0 890 error c2528: '_ptr' : pointer reference illegal error 10 xmemory0 105 error c2528: 'abstract declarator' : pointer reference illegal error 11 xmemory0 107 error c2528: 'abstract declarator' : pointer reference illegal error 12 xmemory0 122 error c2528: 'pointer' : pointer reference illegal error 13 xmemory0 123 error c2528: 'const_pointer' : pointer reference illegal error 14 vector 773 error c2528: '_pval' : pointer reference illegal error 15 vector 1184 error c2535: 'void std::vector<_ty>::push_back(const callable &)' : member function defined or declared error 16 vector 1245 error c2535: 'std::_vector_iterator<_myvec> std::vector<_ty>::insert(std::_vector_const_iterator<_myvec>,_ty)' : member function defined or declared error 17 vector 1494 error c2528: '_ptr' : pointer reference illegal error 18 vector 1658 error c2528: '_pval' : pointer reference illegal
what doing wrong? how make code run?
(my ide microsoft visual studio 2012.)
looking @ code, looks better off storing std::function<double(double, int)>
, , use std::bind
bind objects member functions.
template <typename f> void addsubscriber( const callable & obj, f subscriber) { subscribers.push_back(std::bind(subscriber, obj, _1, _2)); }
or de-couple callable
caller
completely, passing convertible std::function<double(double, int)>
directly:
class caller { public: template <typename f> void addsubscriber(f&& subscriber) { subscribers.emplace_back(std::forward<f>(subscriber)); } void callsubscribers() { (const auto& subscriber : subscribers) { subscriber(1.0, 2); } } private: std::vector<std::function<double(double, int)> subscribers; };
and binding caller side.
caller c; classa a; using namespace std::placeholders; c.addsubscriber(std::bind(&classa::callthis, a, _1, _2));
Comments
Post a Comment