【问题标题】:C++ std::function bind from derived classC++ std::function 从派生类绑定
【发布时间】:2017-12-22 03:39:17
【问题描述】:

如果我有一个带有子类 SetConfigurationData 的基类 MessageWrapper,为什么与子类参数绑定不起作用?

它不应该多态地工作吗?

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;
};

我得到错误: "无法专门化函数模板 'unkown-type std::invoke(Callable &&, Types &&..)'

如果我这样做,它会起作用:

void TestMessageHandler(MessageWrapper &msg_)
{}

【问题讨论】:

  • Title nitpick:你不是在绑定 from 派生类,而是在尝试绑定协变函数。

标签: c++ std-function stdbind


【解决方案1】:

多态不能像这样工作。我会用一个例子来解释。让我们说一下函数。

void TestMessageHandler(SetConfigurationData &msg_)

在其主体中具有特定于子对象的内容。说

msg.child_method()

既然RegisterHandler callback_() 将基类作为参数,那么它应该如何处理这个“msg.child_method()”调用,因为它不是基类方法?

现在,如果我们反过来做会发生什么。以下工作。

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;
};

即使 TestMessageHandler 以 MessageWrapper 作为参数,你也可以将它绑定到以 Child 类 (SetConfigurationData) 作为参数的 callback_。

【讨论】:

  • 这个答案非常接近于清楚地解释这种情况,但它缺少一个非常重要的细节:调用者可以通过引用 MessageWrapper 而不是 SetConfigurationData 来调用函数.例如。 class OtherMessage : public MessageWrapper {}; OtherMessage foo; callback_(foo); -- 这满足MessageWrapper&amp;参数类型的约定,但不满足SetConfigurationData&amp;,这就是不允许协变函数转换的原因。
猜你喜欢
  • 2012-07-07
  • 2019-09-04
  • 1970-01-01
  • 1970-01-01
  • 2019-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多