#c #templates #crtp
#c #шаблоны #crtp
Вопрос:
Я пытаюсь использовать CRTP с небольшим изменением. У меня есть один шаблон производного класса, и я хочу применить его к нескольким базовым классам. Но это либо невозможно, либо я просто не могу правильно использовать синтаксис. Следующий код не компилируется, но, надеюсь, иллюстрирует то, чего я хочу достичь:
template <class Derived> struct BaseCats { /* ... */ };
template <class Derived> struct BaseDogs { /* ... */ };
// ....
template <class Derived> struct BaseN { /* ... */ };
template <template <class> class Base>
struct Wrapper
:
Base<Wrapper> // compile error - Wrapper is not a complete type
{
Wrapper(int n)
{
// I do not want to rewrite or forward this
// constructor or Wrapper's operators
}
};
typedef Wrapper<BaseCats> Cats;
typedef Wrapper<BaseDogs> Dogs;
// ...
typedef Wrapper<BaseN> MyTypeN;
Можно ли это сделать?
Редактировать:
Чего я пытаюсь здесь добиться?
Я переименовал часть кода выше, чтобы использовать метафору «собаки и кошки». Могут существовать такие функции, как:
void BaseCats<Derived>::print() const
{
std::cout << (static_cast<const Derived *>this)->n << " catsn";
}
Но Wrapper
будет содержать конструкторы и операторы, которые являются общими как для собак, так и для кошек. Вид инвертированного полиморфизма, при котором базовый класс имеет специализации. Причина такого решения заключается в том, что конструкторы и операторы не нужно переписывать или пересылать для каждой специализации.
Комментарии:
1. Чего вы пытаетесь достичь с помощью такого дизайна?
2. Вы понимаете, что пытаетесь сделать
Base
производным отDerived
того, что само происходит отBase
того, Что само происходит отDerived
и т. Д.? Вероятно, вам следует объяснить, какова ваша цель, а не как вы ее реализуете, чтобы мы могли предложить альтернативы.3. 1 за интересный дизайн. Не уверен, насколько это было бы полезно
Ответ №1:
Ваша ошибка компиляции может быть решена следующим образом:
Base<Wrapper<Base> >
Вы забыли аргументы шаблона.
Комментарии:
1. Ах да, я действительно думал об этом, но предполагал, что мне придется писать
Base<Wrapper<Base<Wrapper<Base<Wrapper<Base<Wrapper<...> > > > > > > >
2. @paperjam Этого не произойдет, пока база не наследует оболочку.