7

(簡略化された)基本クラスは次のとおりです。

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

ThisWontCompile::DataからSharedObjectにアクセスするための回避策はありますか? ベースオブジェクトから派生したオブジェクトで何ができて、何ができないのでしょうか?

4

1 に答える 1

13

これは実際にはアクセシビリティや友情とは関係がなく、CRTP の使用に関係しています。問題を示す次の例を考えてみましょう。

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

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

問題は、ThisWontCompileへのテンプレート引数として使用される時点では が不完全であるBaseため、 では不完全型としてのみ使用できることBaseです。

特定の問題に対するいくつかの解決策については、この他の質問への回答、特に基本的に次のような特性クラスを使用するというマーティンの推奨事項を参照してください。

// 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>::DataDerivedと の両方で使用できますBaseDerived自体がテンプレートである場合は、特性クラスに部分的な特殊化を使用できます。

于 2011-04-04T05:15:55.287 に答える