卡在模板需求循环中

时间:2009-10-21 16:12:35

标签: c++ templates

我有一个使用“附加”模板的类来添加其他功能,如下所示:

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

3 个答案:

答案 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 );