dimanche 18 février 2018

Passing member function that accepts Base type to class that owns Derived type

Example

#include "DatabaseHandler.h" // class DatabaseHandler
#include "FileLogHandler.h" // class FileLogHandler : public ICustomLogHandler

class LogEvent
{
public:
    virtual void writeWithHandler(DatabaseHandler&) const = 0;
    virtual void writeWithHandler(ICustomLogHandler&) const = 0;
};

class FancyLogEvent : public LogEvent
{ ... };


template <typename T, typename Event>
class LogEventHandler : public ILogEventHandler<Event>
{
public:
    LogEventHandler(T&& handler, void(Event::*func)(T&) const) 
    : m_handlerImpl(std::forward<T>(handler))
    , m_eventFn(func) {}

    void call(const Event& event)
    {
        (event.*m_eventFn)(m_handlerImpl);
    }

private:
    T m_handlerImpl;
    void(Event::*m_eventFn)(T&) const;
};


// ------- Usage -------

// OK
LogEventHandler<DatabaseHandler, LogEvent> h1(DatabaseHandler(), &LogEvent::writeWithHandler);
h1.call(event);

// Error: Candidate constructor not viable: 
// no overload of 'writeWithHandler' matching 
// 'void (LogEvent::*)(CEFEventHandler &) const' for 2nd argument
LogEventHandler<FileLogHandler, LogEvent> h2(FileLogHandler(), &LogEvent::writeWithHandler);
h2.call(event);

Question

How to specify correct template type to accept function-to-Base if class template argument is derived from that Base?

My goal is to pass just pointer-to-member_function to another class whenever that class is the same with type that function accepts or derived from it.

Aucun commentaire:

Enregistrer un commentaire