调用指向派生成员的指针时,指向与对象类型不兼容的成员类型的指针 class

Pointer to member type incompatible with object type when calling a pointer to a member of a derived class

我已经定义了一个 class 模板,例如这个:

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作为实现几个类似classes的标记,并根据特定类别提供适当的专业化。上面的class然后是这样推导出来的:

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

Class Sys 只是一个 class,它为类别 CID_SYS(枚举,值 = 5)的对象提供基本接口,并作为基本 class到接口的实际实现:

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

SysImpl sys;

最后我有一个调用基 class Node<CID_SYS, Base> 成员函数 on_message() 的函数,如下所示:

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

编译器在行 (this->*(call))((T*)frame.data) saying

附近抛出错误

error: pointer to member type 'void (SysImpl::)(const state_info_t*)' is incompatible with object type 'Node<(category_id_t)5u, CAN>'

编译器已经成功猜到要调用的模板函数,只是 "recognize" 似乎 this 不是来自派生的 class.

我想要的是调用从 Node<CID_SYS, CAN> 派生的 class 的任何成员函数,而不仅仅是独立函数(到目前为止运行良好,摘录中未显示以上)。

我错过了什么?

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

这就是为什么你得到错误并需要将 this 转换为 Derived*:

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

当然,这仅在 Derived 实际上 派生自 Node class.

时有效