在我的小部件库中,我想实现某种调用链来初始化 用户提供的VIEW类可能(!)派生自另一个添加的类 一些额外的功能,如:
#include <iostream>
template<typename VIEW>
struct App
{
VIEW view;
void init() {view.initialize(); }
};
template<typename DERIVED>
struct SpecializedView
{
void initialize()
{
std::cout << "SpecializedView" << std::endl;
static_cast<DERIVED*>(this)->initialize();
}
};
struct UserView : SpecializedView<UserView>
{
void initialize() {std::cout << "UserView" << std::endl; }
};
int _tmain(int argc, _TCHAR* argv[])
{
// Cannot be altered to: App<SpecializedView<UserView> > app;
App<UserView> app;
app.init();
return 0;
}
是否可以实现某种调用链(如果用户提供的VIEW类是从“SpecializedView”派生的),那么输出将是:
console output:
SpecializedView
UserView
当然,使用派生自的类型实例化变量app很容易 但是这段代码隐藏在库中,不应该是可以改变的。 换句话说:库代码应该只将用户派生类型作为参数。
答案 0 :(得分:1)
您可以编写另一个函数,在类和基类上调用initialize()
(如果存在)并定义initialize()
方法:
template <class T>
void callInitialize(T* t) {
t->initialize();
IF_EXISTS(base_class<T>::bc::initialize)
callInitialize<base_class<T>::bc>(t);
}
当然,电话的顺序可以颠倒过来。
有关IF_EXISTS
的实施情况,请参阅Is it possible to write a template to check for a function's existence?。此外,base_class<T>
不是标准构造,this answer表明这不能自动完成。语义看起来像这样:
template<T>
struct base_class<T> {
typedef void bc;
};
template<>
struct base_class<UserView> {
typedef SpecializedView<UserView> bc;
};
也许您的框架允许采用半自动方式执行此操作。