C++ C++;CRTP类层次结构
发件人: 现在假设我只需要一个C++ C++;CRTP类层次结构,c++,templates,crtp,C++,Templates,Crtp,发件人: 现在假设我只需要一个派生的对象。这不起作用: derived<derived> obj; 派生obj; 派生的必须是抽象的,还是有一种方法可以实例化它?派生的obj; derived<derived> obj; 不允许,因为派生的是一个模板类,并且内部的派生的尚未完成。它需要有一个像derived这样的类型,没有“just”这样的派生对象,就像不能有“just”std::vector,也不能有float x=sqrt()。该类型需要一个参数,您必须提供它
派生的对象。这不起作用:
derived<derived> obj;
派生obj;
派生的
必须是抽象的,还是有一种方法可以实例化它?派生的obj;
derived<derived> obj;
不允许,因为派生的
是一个模板
类,并且内部的派生的
尚未完成。它需要有一个像derived
这样的类型,没有“just”这样的派生对象,就像不能有“just”std::vector
,也不能有float x=sqrt()代码>。该类型需要一个参数,您必须提供它。这样做是不合法的,因为内部派生的不是一个类,而是一个模板,而不是派生模板的合法参数
通常这样做的方式是拥有一组派生模板实现,然后每个实现都有一个单独的类,用于将该实现实例化为一个具体的类
template <typename T>
struct base
{
};
template <typename T>
struct derived_impl : base<T>
{
};
struct derived : derived_impl<derived>
{
};
template <typename T>
struct derived_of_derived_impl: derived_impl<T>
{
};
struct derived_of_derived : derived_of_derived_impl<derived_of_derived>
{
};
模板
结构基
{
};
模板
结构派生的\u impl:base
{
};
结构派生:派生的\u impl
{
};
模板
派生的\u impl的结构派生的\u:派生的\u impl
{
};
结构派生的派生的:派生的
{
};
对CRTP更深层继承层次结构的支持通常通过在继承层次结构中您自己的类之间“插入”CRTP类来实现:
struct empty
{};
template <class Derived, class Base = empty>
struct crtp_services : Base
{};
class base : public crtp_services<base>
{};
class derived : public crtp_services<derived, base>
{};
class derived_of_derived : public crtp_services<derived_of_derived, derived>
{};
结构为空
{};
模板
结构crtp_服务:基本
{};
类库:公共crtp_服务
{};
派生类:公共crtp_服务
{};
类派生的\u派生的\u:公共crtp\u服务
{};
我自己的回答是:
struct base
{
template <typename T>
struct type
{
// ...
};
};
struct derived
{
template <typename T=derived>
struct type : base::type<T>
{
// ...
};
}
struct derived_from_derived
{
template <typename T=derived_from_derived >
struct type : derived::type<T>
{
// ...
};
};
struct base
{
模板
结构类型
{
// ...
};
};
结构派生
{
模板
结构类型:base::type
{
// ...
};
}
结构派生\u自\u派生
{
模板
结构类型:派生::类型
{
// ...
};
};
现在我可以有一个派生::type obj
。此外,参数化继承工作(例如装饰器模式):
模板
结构从_派生而来
{
模板
结构类型:whatever::type
{
// ...
};
};
派生自_whater::类型obj_whater;
Wikipedia的归属规则需要一个链接,我相信。请链接到您引用的文章。@Mat:short quote=合理使用:)这里有个问题。base
中的函数如何获取指向具体类derived
或derived\u of_derived
的指针?@paperjam:您能为您的问题添加一个示例吗?现在我只能说,您必须将与特定派生类一起工作的代码分解到crtp_服务,这就是它所需要的。支持我的函数base::go(){static_cast(this)->go2();}
。如果我调用derived\u of_-derived::go()
我将到达derived::go2()
而不是derived\u of_-derived::go2()
。希望这有意义@paperjam:然后您需要将'go'移动到crtp_服务类:'crtp_服务::go(){static_cast(this)->go2()}',派生的_派生的::go将从crtp_服务继承,用于派生的_of_派生的::go2。我认为这不起作用。在UML继承图中有多个crtp_服务,base只看到它上面的一个。
struct empty
{};
template <class Derived, class Base = empty>
struct crtp_services : Base
{};
class base : public crtp_services<base>
{};
class derived : public crtp_services<derived, base>
{};
class derived_of_derived : public crtp_services<derived_of_derived, derived>
{};
struct base
{
template <typename T>
struct type
{
// ...
};
};
struct derived
{
template <typename T=derived>
struct type : base::type<T>
{
// ...
};
}
struct derived_from_derived
{
template <typename T=derived_from_derived >
struct type : derived::type<T>
{
// ...
};
};
template <typename whatever>
struct derived_from_whatever
{
template <typename T=derived_from_whatever>
struct type : whatever::type<T>
{
// ...
};
};
derived_from_whatever<derived_from_derived>::type<> obj_whatever;