The code allows you to subscribe to events and publish events via an EventBus class. Events are identified by a source and subject. Events can have a single parameter or they can be 'indexed' and have two parameters (the first being an integer index - I will be using this a lot so wanted a specialization).I don't particularly like the fact that: I need to have an IndexedSubscriptionmethod - it would be nicer to overload the Subscription method, but the compiler doesn't like that.The template argument needs to be specified when calling Subscription and IndexedSubscription.I would like to know if there are any improvements I could make (I am reasonably new to C++ but am experienced in other languages).Example use#include <iostream>#include <typeinfo>#include EventBus.hclass Sources{public:    static EventSource Source1()    {        static EventSource source;        return source;    }    static EventSource Source2()    {        static EventSource source;        return source;    }};class Subjects{public:    static EventSubject<double> Subject1()    {        static EventSubject<double> subject;        return subject;    }};int main(){    EventBus eb;    eb.Subscribe<double&>(Sources::Source1(), Subjects::Subject1(), [](double& data)    {        std::cout << data:  << data << std::endl;    });    eb.Publish<double>(Sources::Source1(), Subjects::Subject1(), 33);    std::cout << Done... ;    std::getchar();    return EXIT_SUCCESS;}Main event bus source#pragma once#include <atomic>#include <vector>#include <map>#include <memory>#include <functional>template<class TData>using EventHandler = std::function<void(TData)>;template<class TData>using IndexedEventHandler = std::function<void(int, TData)>;template<class T>using EventDataType = typename std::remove_reference<typename std::remove_reference<T>::type>::type;class EventIdentifier{private:    int _id;public:    EventIdentifier()    {        static std::atomic_int counter = 1;        _id = counter++;    }    bool operator ==(const EventIdentifier &other) const    {        return _id == other._id;    }    bool operator<(const EventIdentifier& other) const    {        return _id < other._id;    }};class EventSource final : public EventIdentifier{};template<class TData>class EventSubject final : public EventIdentifier{};template<class TData>class IndexedData{private:    int _index;    EventDataType<TData>& _data;public:    IndexedData(int index, EventDataType<TData>&& data) :        _index(index), _data(data)    {    }    int GetIndex()    {        return _index;    }    EventDataType<TData>& GetData()    {        return _data;    }};class EventBus{private:    class EventObserver    {    public:        virtual void Notify(void* data) = 0;    };    template<class TData>    class EventSubscription : public EventObserver    {    private:        EventHandler<TData> _observer;    public:        EventSubscription(EventHandler<TData> observer)        {            _observer = observer;        }        virtual void Notify(void* data) override        {            EventDataType<TData>* pointer = static_cast<EventDataType<TData>*>(data);            _observer(*pointer);        }    };    class EventKey    {    private:        EventIdentifier _source;        EventIdentifier _subject;    public:        EventKey(EventIdentifier source, EventIdentifier subject) :            _source(source), _subject(subject)        {        }        bool operator<(const EventKey& other) const        {            if (_source < other._source)            {                return _subject < other._subject;            }            else            {                return false;            }        }    };    std::map<EventKey, std::vector<std::unique_ptr<EventObserver>>> _observers;public:    template<class TData>    void Subscribe(EventSource source, EventSubject<EventDataType<TData>> subject, EventHandler<TData> observer)    {        Subscribe(EventKey(source, subject), observer);    }    template<class TData>    void IndexedSubscribe(EventSource source, EventSubject<EventDataType<TData>> subject, IndexedEventHandler<TData> observer)    {        Subscribe<IndexedData<TData>&>(EventKey(source, subject), [observer](IndexedData<TData>& data)        {            observer(data.GetIndex(), data.GetData());        });    }    template<class TData>    void Publish(EventSource source, EventSubject<EventDataType<TData>> subject, TData&& data)    {        Publish(EventKey(source, subject), std::forward<TData>(data));    }    template<class TData>    void IndexedPublish(EventSource source, EventSubject<EventDataType<TData>> subject, int index, EventDataType<TData>&& data)    {        Publish(EventKey(source, subject), IndexedData<TData>(index, std::forward<EventDataType<TData>>(data)));    }private:    template<class TData>    void Subscribe(EventKey key, EventHandler<TData> observer)    {        auto& subscripions = _observers[key];        subscripions.push_back(std::make_unique<EventSubscription<TData>>(observer));    }    template<class TData>    void Publish(EventKey key, TData&& data)    {        auto found = _observers.find(key);        if (found != _observers.end())        {            for (auto& observer : found->second)            {                observer->Notify(&data);            }        }    }};
C++ 14 event bus implementation
c++;beginner;event handling;c++14