c++11 - Tricky callback realization (C++) -
i have been trying think out lightweight class delegate static/member functions, functors, closures, etc. in project, necessary pass such entities function arguments, , in addition, used in other cases.
the first time, decided use templates , inheritance , got this:
template<class returntype, class ...args> class callback { private: // struct abstract_invoker { virtual returntype invoke(args...) = 0; }; // template<class function> class sf_invoker : public abstract_invoker { public: sf_invoker(function function) : _function(function) { }; returntype invoke(args ...args) override { return _function(args...); } private: function _function; }; // template<class class> class mf_invoker : public abstract_invoker { using function = returntype (class::*)(args...); public: mf_invoker(class& target, function function) : _target(target), _function(function) { }; returntype invoke(args ...args) override { return (_target.*_function)(args...); } private: class& _target; function _function; }; // -------------------------------------- public: template<class function> callback(function function) { _invoker = new sf_invoker<function>(function); } template<class class> callback(class& object, returntype(class::*function)(args...)) { _invoker = new mf_invoker<class>(object, function); } ~callback() { delete _invoker; } returntype operator() (args ...args) { return _invoker->invoke(args...); } private: abstract_invoker* _invoker; };
actually, method solves problem works bit slow. tried avoid virtual functions , empirically discovered code below works (vs 2014):
template<class returntype, class ...args> class callback { using function = returntype (*)(args...); public: template<class _function> callback(_function function) { auto invoker = [function] (args ...args) -> returntype { return function(args...); }; _invoker = &invoker; } template<class _class> callback(_class& object, returntype (_class::*function)(args...)) { auto invoker = [function, &object] (args ...args) -> returntype { return (object.*function)(args...); }; _invoker = &invoker; } returntype operator()(args ...args) { return (*(function*) _invoker)(args...); } private: void* _invoker; };
obviously, implementation works faster. such method not safe, not know standard well, not know compiler requirements lambda expressions. question is: is magic? or work on of compilers?
your code has issue of lifetime: have think of scope in objects valid (and after dead).
template<class func> callback(func function) { auto invoker = [function] (args ...args) -> returntype { return function(args...); }; _invoker = &invoker; }
invoker
captures state, therefore cannot transformed pointer function. if _invoker
typed function
compiler warn you.
the remark same second overload.
so, if works, it's accidental.
Comments
Post a Comment