2011-04-04 106 views
6

這裏訪問是(簡化的)基類:C++:與CRTP,在派生類定義的類不是基礎類

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 from SharedObject?從基礎對象派生的對象究竟能夠做什麼和不能做什麼?

回答

12

這實際上與可訪問性和友誼無關,它與使用CRTP有關。請考慮以下的例子,還顯示出該問題:

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

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

的問題是,ThisWontCompile是在它被用作模板參數Base的時間不完全的,所以它只能被用作Base一個不完整的類型。

對於您的具體問題的解決方案了一把,諮詢解答this other question,尤其是馬丁的建議,使用traits類,這基本上是這樣的:

// 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可以在兩個Derived使用並在Base。如果Derived本身就是一個模板,那麼可以對特徵類使用部分特化。

+0

因此,我根本無法訪問任何派生類成員? – Septagram 2011-04-04 05:17:57

+0

@Stagram:不直接,不。如果該解決方案適用於您的特定場景,我會考慮鏈接答案中的特質類解決方案。 – 2011-04-04 05:21:48

+2

@Stagram:如果你陳述你實際需要解決的問題,我們可能會在那裏提供幫助。至於你的特定問題,你可以訪問CRTP模板中的實例化類的成員,只要你強制轉換,並且這些成員的使用不會影響類型的內存佈局(即不能使用'static const int '在實例化類型中設置CRTP類中數組的大小)。我認爲這個特性被現代C++設計中的Alexandrescu用於基於策略的C++類層次設計。 – 2011-04-04 08:03:37