Callback system for events in a window I have written a simple window event capture wrapper that gets events that happen to the window, and can be checked anywhere in the program through a global class. I wanted to be able to create a callback anywhere in the program with any event that I have asked to be checked. To hold the data that is returned from the events, I have used a pointer that is allocated whenever an event occurs, so I can grab the data returned later on in the program.

I don't want to use templates to hold the data since that would require a lot of objects to be created, or a lot of vectors for each specific event that I want. I find this to be too clunky, and I wanted a clean, simple solution.

Data that is captured

struct windowEventData
    {
        void *data = nullptr;
        std::string id;
        sf::Event::EventType event;

        bool polled = false;
    };


Window Event Manager

class windowEventManager
    {
        private:
            std::vector&lt;windowEventData&gt; _subscribedEvents;

        public:
            void subscribe(const std::string &amp;id, sf::Event::EventType event);
            void pollEvent(sf::Event event);
            void clearEvents();

            template&lt;typename T&gt;
            T* hasEventPolled(const std::string &amp;id);

            ~windowEventManager();
    };


Grabbing and setting the pointer

void windowEventManager::pollEvent(sf::Event event)
    {
        for (auto &amp;eventCheck : _subscribedEvents)
            {
                if (eventCheck.event == event.type)
                    {
                        switch (event.type)
                            {
                                case sf::Event::KeyPressed:
                                case sf::Event::KeyReleased:
                                    eventCheck.data = new sf::Event::KeyEvent(event.key);
                                    break;
                                case sf::Event::MouseButtonPressed:
                                case sf::Event::MouseButtonReleased:
                                    eventCheck.data = new sf::Mouse::Button(event.mouseButton.button);
                                    break;
                                case sf::Event::MouseWheelMoved:
                                case sf::Event::MouseWheelScrolled:
                                    eventCheck.data = new bool(true);
                                    break;
                                case sf::Event::TextEntered:
                                    eventCheck.data = new sf::String(event.text.unicode);
                                    break;
                                default:
                                    break;
                            }
                        eventCheck.polled = true;
                    }
            }
    }


I clear events before each poll, and in the destructor so I don't have memory leaks/too much on the heap

void windowEventManager::clearEvents()
    {
        for (auto &amp;eventCheck : _subscribedEvents)
            {
                if (eventCheck.data)
                    {
                        delete eventCheck.data;
                        eventCheck.data = nullptr;
                    }
                eventCheck.polled = false;
            }
    }


Finding out if an event has occured

template&lt;typename T&gt;
inline T *windowEventManager::hasEventPolled(const std::string &amp;id)
    {
        auto it = std::find_if(_subscribedEvents.begin(), _subscribedEvents.end(), [id] (windowEventData &amp;dat) { return dat.id == id &amp;&amp; dat.polled; });
        if (it != _subscribedEvents.end())
            {
                return static_cast&lt;T*&gt;((*it).data);
            }

        return nullptr;
    }


Is my use of a void* proper? I figured I could use a union as well for this, but I would rather see if using a pointer would be a good solution.
delete eventCheck.data;


This line invokes undefined behavior, because you aren't allowed to call delete on an incomplete type (and certainly not on void). Both GCC and Clang warn on this line:

(clang++)
prog.cc:4:5: warning: cannot delete expression with pointer-to-'void' type 'void *' [-Wdelete-incomplete]
    delete p;
    ^      ~

(g++)
prog.cc:4:12: warning: deleting 'void*' is undefined
     delete p;
            ^


Anyway, it won't do what you want (whatever that might be).

For an open set of types, the type-safe way to do what you're trying to do is to use type erasure, as seen in library containers such as std::function&lt;void(void)&gt;. (Shameless plug for my CppCon 2014 talk — type erasure is covered starting at 23m00s.) This kind of type-erasure is easy to implement yourself from scratch in about 20 lines of code.

For a closed set of types, you might see whether your compiler of choice supports C++17 std::variant and/or Boost boost::variant; you can use the visit function to perform an operation on a variant in a type-safe way, and of course you wouldn't even need delete at that point because you wouldn't be using pointers, just plain old value semantics. If you can't use Boost, then I don't recommend trying to implement variant yourself.