我正在使用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
的第二个参数?
答案 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
。