Коротко:
Я хочу убедиться, что производный класс реализует функцию-член, требуемую функцией внутри родительского класса CRTP.
Подробнее:
У меня есть код вроде этого
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<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 );
};
Предполагается, что у меня может быть несколько дочерних классов Imp
, которые выполняют разные вещи в myFunc
и принимают свои собственные требуемые параметры. Интерфейс, предоставляемый Base
, затем используется функциями более высокого уровня, которые должны иметь только указатель/ссылку типа Base::Params
и Base
. Моя проблема заключается в том, что любой Imp
предоставляет специализированный myFunc
. Чтобы избежать бесконечной рекурсии Imp
, необходимо реализовать myFunc
.
Моя первая попытка заключалась в добавлении чистой виртуальной функции в CRTP
virtual void myFunc( typename T::Params& p ) = 0;
но это не работает, поскольку Imp
не был полностью определен, когда CRTP
определяется. Этот вопрос использует static_assert
, который заставлял меня думать о том, чтобы сделать то же самое с static_assert
внутри CRTP::myFunc
. Кроме того, я не уверен, что должно быть выражением в статическом утверждении для нестатической функции.
- Можно ли использовать
static_assert
для чего мне нужно? - Это лучший/самый чистый способ гарантировать, что производный класс имеет необходимую функцию?
- Разве я увлекся своим классом, и есть лучший способ сделать что-то?
Спасибо.