2010-05-30 3 views
2

У меня есть CRTP, который не компилируется с g ++ 4.2.1, возможно потому, что производный класс сам является шаблоном? Кто-нибудь знает, почему это не работает или, еще лучше, как заставить его работать? Пример кода и ошибка компилятора приведены ниже.Шаблонный производный класс в CRTP (Curiously Recurring Template Pattern)

Источник: 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

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

  • Derived производной от Base<Derived>, который
  • производной от Derived, который
  • производную от Base<Derived>, который
  • ...

Используйте вместо этого:

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

Спасибо, я не знаю, почему я этого раньше не заметил. – Butterwaffle

+2

@Butterwaffle, это потому, что: D - очень смешная улыбка, вы не хотели ее удалять: D – Max