user2654735
user2654735

Reputation: 323

C++ std::function bind from derived class

If I had a base class MessageWrapper, with a child class SetConfigurationData, why does binding with a child class parameter not work?

Shouldn't it work polymorphically?

Class MessageHandler
{
    public:
    void RegisterHandler(std::function<void(MessageWrapper &)> callback_)
    {}
};

class Testing
{
    public:

    Testing(MessageHandler &handler_)
        : m_Handler(handler_)
    {
        m_Handler.RegisterHandler(std::bind(&Testing::TestMessageHandler, this, std::placeholders::_1));
    }

    void TestMessageHandler(SetConfigurationData &msg_)
    {}

    MessageHandler m_Handler;
};

I get the error: "Failed to specialize function template 'unkown-type std::invoke(Callable &&, Types &&..)'

It works if I do this:

void TestMessageHandler(MessageWrapper &msg_)
{}

Upvotes: 3

Views: 1268

Answers (1)

Santosh
Santosh

Reputation: 59

Polymorphism cannot work like this. I will explain with an example. Let's say the function.

void TestMessageHandler(SetConfigurationData &msg_)

has something specific to the child object in it's body. Say

msg.child_method()

Now since RegisterHandler callback_() takes base class as argument, what should it do with this "msg.child_method()" call since it's not a base class method ?

Now, what happens if we do it the other way round. The following works.

class MessageWrapper
{
};

class SetConfigurationData : public MessageWrapper
{
    public:
    void RegisterHandler(std::function<void(SetConfigurationData&)> callback_)
    {}
};

class MessageHandler
{
};

class Testing
{
    public:

        Testing(SetConfigurationData &handler_)
            : m_Handler(handler_)
        {
            m_Handler.RegisterHandler(std::bind(&Testing::TestMessageHandler, this, std::placeholders::_1));
        }

        void TestMessageHandler(MessageWrapper &msg_)
        {}

        SetConfigurationData m_Handler;
};

Even though TestMessageHandler takes MessageWrapper as argument, u can bind it to callback_ which takes Child class (SetConfigurationData) as argument.

Upvotes: 2

Related Questions