C++:使用 CRTP,派生类中定义的类无法在基类中访问

发布于 2024-10-30 19:29:47 字数 503 浏览 7 评论 0原文

这是(简化的)基类:

template <class T>
class SharedObject
{
protected:
    QExplicitlySharedDataPointer <typename T::Data> d;
};

这是派生类:

class ThisWontCompile : public SharedObject <ThisWontCompile>
{
private:
    friend class SharedObject;
    struct Data : public QSharedData
    {
        int id;
    };
};

是否有任何解决方法可以从 SharedObject 访问 ThisWontCompile::Data?对于从基础对象派生的对象到底能做什么、不能做什么?

Here is the (simplified) base class:

template <class T>
class SharedObject
{
protected:
    QExplicitlySharedDataPointer <typename T::Data> d;
};

And here is the derived:

class ThisWontCompile : public SharedObject <ThisWontCompile>
{
private:
    friend class SharedObject;
    struct Data : public QSharedData
    {
        int id;
    };
};

Is there any workaround to access ThisWontCompile::Data from SharedObject? What exactly can and what exactly cannot be done with the derived object from the base object?

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

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

发布评论

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

评论(1

ζ澈沫 2024-11-06 19:29:47

这实际上与可达性和友好性无关,而是与CRTP的使用有关。考虑以下也显示该问题的示例:

template <class T>
struct Base
{
    typedef typename T::Data Data;
};

struct ThisWontCompile : public Base<ThisWontCompile>
{
    struct Data { };
};

问题是 ThisWontCompile 在用作 Base 的模板参数时不完整,因此只能使用它作为 Base 中的不完整类型。

如需针对您的特定问题的一些解决方案,请参阅此其他问题的答案,特别是 Martin 建议使用特征类,它基本上如下所示:

// Base
template <typename T>
struct BaseTraits;

template <typename T>
struct Base
{
    typedef typename BaseTraits<T>::Data Data;
};

// Derived
struct Derived;

template <>
struct BaseTraits<Derived>
{
    struct Data { };
};

struct Derived : public Base<Derived>
{
};

typename BaseTraits::Data 可以在 Derived 和 in 中使用基础。如果 Derived 本身就是一个模板,则可以对特征类使用部分特化。

This actually isn't related to the accessibility and friendship, it's related to the use of CRTP. Consider the following example that also exhibits the problem:

template <class T>
struct Base
{
    typedef typename T::Data Data;
};

struct ThisWontCompile : public Base<ThisWontCompile>
{
    struct Data { };
};

The problem is that ThisWontCompile is incomplete at the time it is used as a template argument to Base, so it can only be used as an incomplete type in Base.

For a handful of solutions to your specific problem, consult the answers to this other question, especially Martin's recommendation to use a traits class, which would basically look like this:

// Base
template <typename T>
struct BaseTraits;

template <typename T>
struct Base
{
    typedef typename BaseTraits<T>::Data Data;
};

// Derived
struct Derived;

template <>
struct BaseTraits<Derived>
{
    struct Data { };
};

struct Derived : public Base<Derived>
{
};

typename BaseTraits<Derived>::Data can be used in both Derived and in Base. If Derived is itself a template, you can use a partial specialization for the traits class.

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