【问题标题】:Pointer to member type incompatible with object type when calling a pointer to a member of a derived class调用派生类成员指针时指向成员类型的指针与对象类型不兼容
【发布时间】:2017-03-09 00:39:38
【问题描述】:

我已经定义了一个这样的类模板:

template <const category_id_t category, class Base>
class Node : public Base
{
...
    template <typename Derived, class T>
    void on_message( const frame_t& frame, void (Derived::*call)(const T*) )
    {
        if ( frame.length == sizeof(T) )
            (this->*(call))((T*)frame.data);
    }
}

参数category 用作实现几个类似类并根据特定类别提供适当专业化的标记。然后上面的类是这样派生的:

template <class Base>
class Sys : public Node<CID_SYS, Base>
{
    Sys() : Node<CID_SYS, Base>() { /* ... */ }
    ....
};

Sys 类只是为 CID_SYS 类别的对象(枚举,值 = 5)提供基接口并用作接口实际实现的基类:

class SysImpl : public Sys<CAN>
{
    ...
    /* Parse remote notifications */
    void on_notify( const state_info_t* ) { /* ... */ }
};

SysImpl sys;

最后我有一个函数可以像这样调用基类Node&lt;CID_SYS, Base&gt;成员函数on_message()

void foo(const frame_t& frame)
{ sys.on_message(frame, &SysImpl::on_notify ); }

编译器在(this-&gt;*(call))((T*)frame.data) 语句周围抛出一个错误

错误:指向成员类型“void (SysImpl::)(const state_info_t*)”的指针与对象类型“Node”不兼容

编译器已经成功猜到要调用什么模板函数,只是它似乎没有“识别”出this来自派生类。

我想要调用从Node&lt;CID_SYS, CAN&gt; 派生的类的任何成员函数,而不仅仅是独立函数(目前运行良好,上面的摘录中没有显示)。

我错过了什么?

【问题讨论】:

  • 你试过static_cast this 到合适的类型吗?
  • 我建议你看看有多少standard library alhorithm functions 使用模板处理谓词和回调等事情。我还建议您阅读有关std::functionstd::bind 的信息。
  • 至于你的错误,在on_message 函数中this 不是指向SysImpl 对象的指针。
  • @Someprogrammerdude 我认为 OP 使用 CRTP 所以它实际上可以指向SysImpl
  • @W.F.谢谢!做到了!我对模板和所有的爵士乐有点生疏了,我猜,但这很管用。

标签: c++ templates derived-class pointer-to-member


【解决方案1】:

on_message 函数中,变量this 不是指向SysImpl 的指针,它的类型是Node&lt;CID_SYS, CAN&gt;*Node 模板类没有成员 on_notify,因此您不能在 Node 的实例上调用它。它必须在 Derived 的实例上调用(应该是 SysImpl)。

这就是为什么您会收到错误并需要将this 转换为Derived*

(static_cast<Derived*>(this)->*(call))(...);

当然,这只有在Derived 实际上 派生自Node 类时才有效。

【讨论】:

  • 我们可以执行static_assert来检查Derived是否与Base相同
猜你喜欢
  • 2021-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-12
  • 2018-03-24
  • 1970-01-01
  • 2014-06-16
相关资源
最近更新 更多