mercredi 2 septembre 2015

Ensure that class derived from parent CRTP class implements function

Brief:

I want to make sure a derived class implements a member function required by a function within the parent CRTP class.

Detail:

I have some code like this

class Base
{
public:
    class Params
    {
    public:
        virtual ~Params() {}
    };

    virtual void myFunc( Params& p ) = 0;
};

template< typename T >
class CRTP : public Base
{
public:
    virtual void myFunc( Base::Params& p ) override
    {
        typename T::Params& typedParams = dynamic_cast<typename T::Params&>( p );
        static_cast<const T*>( this )->myFunc( typeParams );
    }

};

class Imp : public CRTP<Imp>
{
public:
    class Params : public CRTP<Imp>::Params
    {
    public:
        virtual ~Params() {}

        int x, y, z;
    };

    virtual void myFunc( Imp::Params& p );
};

The intention is that I can have multiple Imp child classes all doing different things in myFunc and accepting their own required parameters. The interface provided by Base is then utilized by higher level functions that only need to have a pointer/reference of type Base::Params and Base. My problem is making sure that any Imp provides a specialized myFunc. To avoid infinite recursion Imp must implement myFunc.

My first try was adding a pure virtual function to CRTP

virtual void myFunc( typename T::Params& p ) = 0;

but that doesn't work as Imp hasn't been fully defined when CRTP is being defined. This question uses a static_assert which made me think of doing the same with the static_assert within CRTP::myFunc. Except I'm not sure what should be the expression in the static assertion for a non-static function.

  1. Can I use a static_assert for what I need?
  2. Is that the best/cleanest way to ensure the derived class has the needed function?
  3. Have I got carried away with my class design and there is a better way of doing things?

Thanks.

Aucun commentaire:

Enregistrer un commentaire