将接受Base类型的成员函数传递给拥有Derived类型的类

时间:2018-02-18 13:05:17

标签: c++11 templates overloading pointer-to-member

示例

在上面的示例中,我尝试在基于模板的类中存储重载函数的指向成员函数的指针。 问题是重载函数使用Base类作为参数,当前类是Derived类的模板类。

处理程序

#include <iostream>
#include <string>

class HandlerA
{
public:
    void foo(const std::string& m)
    {
        std::cout << "HandlerA: " << m << '\n';
    }
};

class IBaseHandlerB
{
public:
    virtual void bar(const std::string& m) = 0;
};

class HandlerB : public IBaseHandlerB
{
public:
    virtual void bar(const std::string& m) override
    {
        std::cout << "HandlerB: " << m << '\n';
    }
};

事件

class Event
{
public:
    virtual void write(HandlerA&) const = 0;
    virtual void write(IBaseHandlerB&) const = 0;
};

class FancyEvent : public Event
{
public:
    virtual void write(HandlerA& h) const override
    {
        h.foo("FancyEvent");
    }

    virtual void write(IBaseHandlerB& h) const override
    {
        h.bar("FancyEvent");
    }
};

包装和使用示例

template <typename T, typename Event>
class HandlerWrapper
{
public:
    HandlerWrapper(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 -------
int main(void)
{
    FancyEvent event;

    // OK
    HandlerWrapper<HandlerA, Event> h(HandlerA(), &Event::write);
    h.call(event);

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

    return 0;
}

问题

如果类模板参数是从该Base派生的,如何指定正确的模板类型来接受函数到基础?

我的目标是,只要该类与函数接受或派生的类型相同,就将指向成员函数的指针传递给另一个类。

0 个答案:

没有答案