CRTP 中的模板化派生类(奇怪的重复模板模式)
我使用了不能用 g++ 4.2.1 编译的 CRTP,也许是因为派生类本身就是一个模板?有谁知道为什么这不起作用,或者更好的是,如何使其起作用?示例代码和编译器错误如下。
来源: 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*>’
I have a use of the CRTP that doesn't compile with g++ 4.2.1, perhaps because the derived class is itself a template? Does anyone know why this doesn't work or, better yet, how to make it work? Sample code and the compiler error are below.
Source: 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;
}
Compiler errors
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*>’
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
有一种方法可以使 CRTP 适用于模板派生类,但需要注意的是它应该始终是模板。
适用于 gcc 4.4.7 甚至更旧的版本,无法确定。
There is a way to make CRTP works for a template derived class, with a caveat that it should always be a template.
Works with gcc 4.4.7 and maybe older, can't check for sure.
CRTP 的想法是拥有一个知道其派生类是什么类型的基类 - 不要让基类从其派生类派生。
否则,您将遇到以下情况:
Derived
派生自Base
,后者Derived
,后者Base< ;Derived>
,其中请改用以下内容:
The idea of CRTP is to have a base class that knows of what type its derivative is - not to let the base class derive from its derivative.
Otherwise you'd have the following situation:
Derived
derives fromBase<Derived>
, whichDerived
, whichBase<Derived>
, whichUse the following instead: