我有一个使用“附加”模板的类来添加其他功能,如下所示:
template< class T >
class AddOn_A
{
public:
int SomeFuncA()
{
T* pT = static_cast< T* >( this );
return pT->DoSomething() + 1;
};
};
class CMyClass : public AddOn_A< CMyClass >
{
public:
int DoSomething()
{
return 100;
};
};
int _tmain(int argc, _TCHAR* argv[])
{
CMyClass A;
_ASSERT( A.SomeFuncA() == 101 );
return 0;
}
现在我想扩展这一点,以便CMyClass可以接受AddOn_B等不同的附加组件。
template< class T >
class AddOn_B
{
public:
int SomeFuncB()
{
T* pT = static_cast< T* >( this );
return pT->DoSomething() + 2;
};
};
template< class AddOn >
class CMyClass : public AddOn
{
public:
int DoSomething()
{
return 100;
};
};
int _tmain(int argc, _TCHAR* argv[])
{
// error C3203: 'AddOn_A' : unspecialized class template can't be used as a template argument for template parameter 'AddOn', expected a real type
// error C2955: 'AddOn_A' : use of class template requires template argument list
CMyClass< AddOn_A > A;
_ASSERT( A.SomeFuncA() == 101 );
// same errors here
CMyClass< AddOn_B > B;
_ASSERT( B.SomeFuncB() == 102 );
return 0;
}
不幸的是,每个Add_On都需要CMyClass作为模板参数,这需要Add_On等...我在需求循环中。
我是否可以使用一些模板魔法来获取我正在寻找的功能?有没有更好的方法呢?
谢谢, PaulH
答案 0 :(得分:2)
如果我理解你的问题(不确定),那么你需要的是模板模板参数:
template< template<class> class AddOn >
class CMyClass : public AddOn< CMyClass<AddOn> > {
// ...
};
答案 1 :(得分:0)
显然你正试图使用着名的Curiously Recurring Template Pattern。
我不确定你究竟想做什么,但你可能会找到另一种解决方案:
如果你使用了两个课程怎么办?
class Base {};
class MyClass: public AddOn<Base> {};
您也可以使用基于策略的方法:
class PolicyA_A {};
class PolicyA_B {};
class PolicyB_A {};
class PolicyB_B {};
template <class PolicyA, class PolicyB>
class MyClass: private PolicyA, private PolicyB {};
typdef MyClass<PolicyA_A, PolicyB_A> MyClassAA;
我们的想法是将部分工作委托给政策以增加灵活性。
最后但并非最不重要的是,您可以使用Decorator方法:
class Base {};
template <class T>
class AddOn_A: public T {};
class MyClass: public AddOn_A< AddOn_B< Base > > {};
它允许您通过抑制多重继承并使层次结构呈线性来消除虚拟继承。
答案 2 :(得分:0)
为什么你不能只使用:
CMyClass< AddOn_A<CMyClass> > A;
_ASSERT( A.SomeFuncA() == 101 );