通过继承类的成员编写器

时间:2017-10-25 06:37:27

标签: c++ delegates bind functor

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

我想使用这个简化代码的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 */ }
};

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

// 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的第二个参数只接受父级成员仿函数类型。所以我无法通过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的第二个参数?

1 个答案:

答案 0 :(得分:2)

虽然立即解决方案是static_cast,但我认为您不应将init_and_bind转换为模板。生成的代码将始终相同。唯一的区别可能在于如何进行实际演员表。

所以你会得到相当多的代码膨胀,这都是因为差异非常小。我建议你把这种差异封装起来。为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