2012-12-18 13 views
2

在我的小部件库中,我想实现某种调用链来初始化用户提供的VIEW类的 ,该类可能(!)从另一个类派生,该类增加了 一些附加功能此:CRTP在调用链中的使用

#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 

当然它很容易安装从 派生的类型的反转变量应用程序,但此代码隐藏在库中,不应该是可变的。换句话说:库代码应该只将用户派生类型作为参数。

+2

明确的公共初始化方法非常糟糕。 – Puppy

+1

@DeadMG:上面的示例代码显然被剥离到了最低限度!我不想添加更多的代码来描述我的意图。 – fhw72

回答

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); 
} 

当然,调用的顺序可以颠倒。

请参阅Is it possible to write a template to check for a function's existence?关于执行IF_EXISTS。此外,base_class<T>不是标准构造,并且this answer暗示这不能自动完成。语义看起来像这样:

template<T> 
struct base_class<T> { 
    typedef void bc; 
}; 

template<> 
struct base_class<UserView> { 
    typedef SpecializedView<UserView> bc; 
}; 

也许你的框架允许一个半自动的方式来做到这一点。