Home > Mobile >  Can I make use on templates when implementing different interfaces in the same way?
Can I make use on templates when implementing different interfaces in the same way?

Time:11-30

I have many interfaces for different listeners, the all look like this:

class ListenerA
{
public:
    virtual void
    onEventA(const EventA&) = 0;
};

class ListenerB
{
public:
    virtual void 
    onEventB(const EventB&) = 0;
};

When testing, I always end up just collecting those events in a std::vector for analyzing them afterwards in a specific test suite. Those event collectors all look the same like this one for example:

class EventACollector : public ListenerA
{
public:

    const auto&
    events() const
    {
        return m_events;
    }

private:

    void
    onEventA(const EventA& event) override
    {
        m_events.emplace_back(event);
    }

    std::vector<EventA> m_events;
};

Is there a way to template an EventTCollector, so that I do not have to write it every time? Given that the virtual function name does change for every listeners?

CodePudding user response:

C does not have introspection, so you cannot find the virtual function in ListenerA. The other parts can go in a templated base class, but the override you'll need to define manually.

Modern C would use a std::function<void(EventA)> instead of a named interface, but that won't help you as a user of that old interface.

CodePudding user response:

Supposed you make your interface a template (this isnt necessary, but will make the collector more straight forward):

template <typename Event>
class ListenerA {
public:
    using event_type = Event;
    virtual void onEventA(const event_type&) = 0;
};

Then the collector can be:

template <typename Listener>
class EventACollector : public Listener {
public:
    const auto& events() const { return m_events; }
private:
    void onEventA(const EventA& event) override {
        m_events.emplace_back(event);
    }
    std::vector<typename Listener::event_type> m_events;
};
  • Related