Stuck in a pattern requirement loop

I have a class that uses the "add-on" pattern to add additional functionality as shown below:

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

      

Now I would like to expand on this so that CMyClass can accept various additions like 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;
}

      

Unfortunately every Add_On item requires CMyClass as a template parameter, which requires Add_On, etc. I'm in a demand loop.

Is there some kind of template magic I can use to get the functionality I'm looking for? Is there a better way to do this?

Thanks, PaulH

+2


source to share


3 answers


Apparently you are trying to use the famous curious repeating pattern pattern .

I'm not sure what you exactly want to do, but you can get away with another solution:

What if you used two classes:

 class Base {};

 class MyClass: public AddOn<Base> {};

      

You can also take a political approach:



 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;

      

The idea is to delegate some of the work to politicians to add flexibility.

Finally, you can use Decorator :

 class Base {};

 template <class T>
 class AddOn_A: public T {};

 class MyClass: public AddOn_A< AddOn_B< Base > > {};

      

This allows you to get rid of virtual inheritance by suppressing Multi Inheritance and making the hierarchy linear.

0


source


If I understood your question correctly (not sure), then you need a template template argument:



template< template<class> class AddOn >
class CMyClass : public AddOn< CMyClass<AddOn> > {
  // ...
};

      

+2


source


Why can't you just use:

CMyClass< AddOn_A<CMyClass> > A;
_ASSERT( A.SomeFuncA() == 101 );

      

0


source







All Articles