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;