mardi 29 septembre 2015

Member function pointer cast, from Derived to Base class

I'm doing the following:

  • Taking a member function pointer with 3 params from a derived class.
  • Casting it to a member function pointer from the base class with 0 params.
  • Casting it to the base class with the 3 params back.
  • Calling it.

It works fine (so far), should i keep it? Thanks

EventsWarehouse is used to store and invoke events:

#include <iostream>
#include <functional>
#include <unordered_map>

class EventsWarehouse
{
public:
    typedef std::tuple<AView*, void (AView::*)()>           box_t;
    typedef std::unordered_multimap<std::string, box_t>     boxes_t;

    void        storeEvent(std::string const &event, AView *v, void (AView::*callback)())
        {
            this->_events.insert(std::make_pair(event, std::make_tuple(v, callback)));
            return ;
        }

    template<typename... Args>
    bool        fireEvent(std::string const &event, Args... args)
        {
            auto                it = this->_events.find(event);
            AView               *v;
            void                (AView::*callback_)();
            void                (AView::*callback)(Args...);

            for (; it != this->_events.end(); it++)
            {
                v = std::get<0>(it->second);
                callback_ = std::get<1>(it->second);
                /*
                ** CAST #2
                ** <void (AView::*)()>
                **  to
                ** <void (AView::*)(std::string, int, double)>
                **  before call
                */
                callback = reinterpret_cast<void (AView::*)(Args...)>(callback_);
                (v->*callback)(args...);
            }
            return (true);
        }
private:
    boxes_t         _events;

};

View classes stored in the above class:

class AView
{
protected:
    AView(){}
};

class DerivedView : public AView
{
public:
    void    fooCallback(std::string s, int i, double d)
        {
            std::cout << "DerivedView::fooCallback received " << s << ", " << i << ", " << d << std::endl;
            return ;
        }
};

Main:

int                         main(void)
    {
        DerivedView     dv;
        EventsWarehouse ewh;

        /*
        ** CAST #1
        ** <void (DerivedView::*)(std::string, int, double)>
        **  to
        ** <void (AView::*)()>
        **  for storing purpose
        */
        ewh.storeEvent("event 1", &dv, reinterpret_cast<void (AView::*)()>(&DerivedView::fooCallback));
        ewh.fireEvent("event 1", std::string("Hello World"), 42, 84.42);
        return (0);
    }

Aucun commentaire:

Enregistrer un commentaire