C++ CRTP 类层次结构

发布于 2024-12-11 17:08:56 字数 767 浏览 0 评论 0原文

来自维基百科

// The Curiously Recurring Template Pattern (CRTP)
template <typename T>
struct base
{
    // ...
};
struct derived : base<derived>
{
    // ...
};

现在如果我想要衍生自_衍生,我可以写:

// The Curiously Recurring Template Pattern (CRTP)
template <typename T>
struct base
{
    // ...
};
template <typename T>
struct derived : base<T>
{
    // ...
};
struct derived_from_derived : derived <derived_from_derived>
{
    // ...
};

现在假设我只想要一个派生对象。这是行不通的:

derived<derived> obj;

衍生必须是抽象的,还是有办法实例化它?

From Wikipedia:

// The Curiously Recurring Template Pattern (CRTP)
template <typename T>
struct base
{
    // ...
};
struct derived : base<derived>
{
    // ...
};

Now if I want derived_from_derived, I can write:

// The Curiously Recurring Template Pattern (CRTP)
template <typename T>
struct base
{
    // ...
};
template <typename T>
struct derived : base<T>
{
    // ...
};
struct derived_from_derived : derived <derived_from_derived>
{
    // ...
};

Now suppose I just want a derived object. This doesn't work:

derived<derived> obj;

Does derived have to be abstract, or is there a way to instantiate it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

只怪假的太真实 2024-12-18 17:08:56

我自己的答案是这样的:

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;

My own answer is this:

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>
    {
        // ...
    };
};

Now I can have a derived::type<> obj. Also, parametized inheritance works (e.g. decorator pattern):

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;
何以心动 2024-12-18 17:08:56

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>
{};

Support for deeper inheritance hierarchies with CRTP usually is implemented by "inserting" CRTP classes between your own classes in the inheritance hierarchy:


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>
{};

左耳近心 2024-12-18 17:08:56

这样做是不合法的,因为内部派生不是一个类,而是它本身是一个模板,而不是派生模板的合法参数。

通常完成此操作的方法是拥有一组派生模板实现,然后每个实现都有一个单独的类,用于将该实现实例化为具体类。

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>
{

};

It's not legal to do that, since the inner derived is not a class, but is itself a template, and not a legal argument for the derived template.

The way that this is usually done is to have a set of derived templates implementations, and then each implementation has a separate class which is used to instantiate that implementation as a concrete class.

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>
{

};
冬天旳寂寞 2024-12-18 17:08:56
derived<derived> obj;

不允许,因为 衍生 是一个 模板 类,并且内部 衍生 尚未完成。它需要具有类似于 衍生 的类型。

derived<derived> obj;

is not allowed because derived is a template class and the inner derived is not yet complete. It needs to have a type like derived<int>.

同尘 2024-12-18 17:08:56

不存在“仅”派生对象之类的东西,就像您不能“仅”std::vector 一样,也不可能具有 float x = sqrt(); 。该类型需要一个参数,并且您必须提供它。

There's no such thing as "just" a derived object, just like you cannot have "just" std::vector, nor can you have float x = sqrt();. The type requires an argument, and you must provide it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文