Шаблонный производный класс в CRTP (Любопытно повторяющийся шаблон) - PullRequest
4 голосов
/ 31 мая 2010

Я использую CRTP, который не компилируется с g ++ 4.2.1, возможно, потому что производный класс сам является шаблоном? Кто-нибудь знает, почему это не работает или, что еще лучше, как заставить это работать? Пример кода и ошибка компилятора приведены ниже.

Источник: foo.C

#include <iostream>

using namespace std;

template<typename X, typename D> struct foo;

template<typename X> struct bar : foo<X,bar<X> >
{
  X evaluate() { return static_cast<X>( 5.3 ); }
};

template<typename X> struct baz : foo<X,baz<X> >
{
  X evaluate() { return static_cast<X>( "elk" ); }
};

template<typename X, typename D> struct foo : D
{
  X operator() () { return static_cast<D*>(this)->evaluate(); }
};

template<typename X, typename D>
void print_foo( foo<X,D> xyzzx )
{
  cout << "Foo is " << xyzzx() << "\n";
}

int main()
{
  bar<double> br;
  baz<const char*> bz;

  print_foo( br );
  print_foo( bz );

  return 0;
}

Ошибки компиляции

foo.C: In instantiation of ‘foo<double, bar<double> >’:
foo.C:8:   instantiated from ‘bar<double>’
foo.C:30:   instantiated from here
foo.C:18: error: invalid use of incomplete type ‘struct bar<double>’
foo.C:8: error: declaration of ‘struct bar<double>’
foo.C: In instantiation of ‘foo<const char*, baz<const char*> >’:
foo.C:13:   instantiated from ‘baz<const char*>’
foo.C:31:   instantiated from here
foo.C:18: error: invalid use of incomplete type ‘struct baz<const char*>’
foo.C:13: error: declaration of ‘struct baz<const char*>’

1 Ответ

2 голосов
/ 31 мая 2010

Идея CRTP состоит в том, чтобы иметь базовый класс, который знает, к какому типу относится его производная, а не позволять базовому классу наследовать от его производной.
В противном случае у вас будет следующая ситуация:

  • Derived происходит от Base<Derived>, что
  • происходит от Derived, что
  • происходит от Base<Derived>, что
  • ...

Вместо этого используйте следующее:

template<typename X, typename D> struct foo // : D
// ...                                         ^ remove that
...