I made this simple event system: template<typename Func, typename Args> class Event { public: static void dispatch(Args args) { for (auto listener : listeners) listener(args); } static void attach(Func func) { listeners.emplace_back(func); } private: static std::vector<Func> listeners; }; template<typename Func, typename Args> std::vector<Func> Event<Func, Args>::listeners; What I wanted to do is to let me create any sort of event without needing to do a lot more code, so for example in this code, if I want to add a `KeyEvent`, for example, I could do this: struct KeyArguments { Point point; int someInt; }; class KeyEvent : public Event<std::function<void(KeyArguments)>, KeyArguments> { }; And to use such code: Point tempPoint{ 1,2 }; KeyEvent::attach(func); KeyEvent::attach([](KeyArguments args) { std::cout << "Hello\n";}); KeyArguments args; args.point = tempPoint; args.someInt = 20; KeyEvent::dispatch(args); I also wanted to make the design reachable from anywhere in the code, this is why I used `static` keyword, and this is the part that doesn't really "feel" good. Should I really be using static in this case? Is there any cons in using such design? I feel like using `template `for this case is a bit overkill. For each event create a "new" class (the struct doesn't bother me). Do you think there is a way around that? Is it as bad as I think it is? EDIT: I changed the `vector<Func>` to `unordered_map` to allow dettaching, here is the updated code: template<typename Func, typename Args> class Event { public: static void dispatch(Args args) { for (auto listener : listeners) listener.second(args); } static void attach(const std::string& id, Func func) { listeners.insert({ id, func }); } static void dettach(const std::string& id) { listeners.erase(id); } private: static std::unordered_map<std::string, Func> listeners; }; template<typename Func, typename Args> std::unordered_map<std::string, Func> Event<Func, Args>::listeners;