![](/img/trans.png)
[英]CRTP (Curiously Recurring Template Pattern) using a generic base template class instead of the derived class
[英]Templated derived class in CRTP (Curiously Recurring Template Pattern)
我使用了不能用 g++ 4.2.1 编译的 CRTP,也许是因为派生类本身就是一个模板? 有谁知道为什么这不起作用,或者更好的是,如何使它起作用? 示例代码和编译器错误如下。
#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*>’
CRTP 的想法是让基类知道它的派生类是什么类型——而不是让基类从它的派生类派生。
否则会出现以下情况:
Derived
派生自Base<Derived>
,其中Derived
,其中Base<Derived>
,其中请改用以下内容:
template<typename X, typename D> struct foo // : D
// ... ^ remove that
有一种方法可以使 CRTP 适用于模板派生类,但需要注意的是它应该始终是模板。
#include <iostream>
#include <typeinfo>
template<template <class> class Derived, class T>
struct A{
void interface(){
static_cast<Derived<T>*>(this)->impl();
}
};
template<class T>
struct B: public A<B, T>
{
void impl(){
std::cout << "CRTP with derived templates are real\n";
std::cout << "Tempate argument is " << typeid(T).name() << "\n";
}
};
int main(void)
{
B<char>().interface();
B<double>().interface();
B<void>().interface();
return 0;
}
适用于 gcc 4.4.7 甚至更旧的版本,无法确定。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.