c++ - 传递继承类的成员仿函数

标签 c++ delegates bind functor

我正在使用 C++ 编写游戏代码。我想将 Child 的成员函数绑定(bind)到委托(delegate)中。

我想使用 init_and_bind 函数,如下简化代码:

class Parent {
protected:
    Widget* widget;
};

class Child : public Parent {
public:
    void foo() {
        widget->init_and_bind(this, &Child::bar);
    }

    void bar() { /* do something */ }
};

我想在Widget类中实现init_and_bind,所以我实现了如下代码:

// pre-defined in engine
void Delegate::bind(Parent* object, void(Parent::* function)());

void Widget::init_and_bind(Parent* object, void(Parent::* function)()) {
    init();
    delegate->bind(object, function);
}

但是这不起作用。因为init_and_bind的第二个参数只接受Parent的成员仿函数类型。所以我无法传递 Child 的成员仿函数。所以我尝试使用模板和reinterpret_cast:

template<typename T>
void Widget::init_and_bind(Parent* object, void(T::* function)()) {
    init();
    delegate->bind(object, function); // error
    delegate->bind(object, reinterpret_cast<void(Parent::*)()>(function); // error
}

但它也不起作用。因为它无法将 Child 的仿函数转换为 Parent 的仿函数。

那么,init_and_bind 的第二个参数应该是什么类型?

最佳答案

虽然直接的解决方案是static_cast,但我认为您不应该将init_and_bind 变成模板。生成的代码总是几乎相同。唯一的区别可能在于实际 Actor 阵容的执行方式。

所以你会得到相当多的代码膨胀,这都是因为一个非常小的差异。我建议您将这种差异封装起来。为此,向 Widget 添加一个辅助类型:

class Widget {
  struct MemFunc {
    void(Parent::* function)();
    template<class T>
    MemFunc(void(T::* func)()) :
      function(static_cast<void(Parent::*)()>(func))
    {}
  };

  void init_and_bind(Parent* object, MemFunc mf) {
    init();
    delegate->bind(object, mf.function);
  }
};

这样,实际上只有需要模板化的一小段代码才被模板化。最好的是,它在调用方上透明地发生。它甚至可能不会引起任何肿胀。因为您的原始非模板版本无论如何都要求调用者static_cast

关于c++ - 传递继承类的成员仿函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46925511/

相关文章:

c++ - 确保用户使用 shared_ptr 而不是常规 ptr 的正确方法是什么?

iphone - 将在 Interface Builder 中创建的 UITabBarController 设置为委托(delegate)

javascript - jQuery 绑定(bind)提交导致问题

dns - 在 ubuntu 中绑定(bind)时设置 dkim setup dns zone 语法错误

c++ - cpp字节文件读取

c++ - 计算 thrust::device_vector 上的梯度

c++ - 线程完成后删除Qt Thread中的对象

ios - 快速从单独的 View Controller 调用函数

c# - 在接口(interface)中实现委托(delegate)

javascript - 在异步函数上调用 `bind()` 部分有效