template <typename T>
class Base
{
private:
typename T::B c;
};
class A : public Base<A>
{
public:
class B;
};
這樣的事情甚至可能嗎? VC++ 2013說B是不是A的成員從模板類Base <A>衍生出A類,以便Base <A>可以使用A :: B?
template <typename T>
class Base
{
private:
typename T::B c;
};
class A : public Base<A>
{
public:
class B;
};
這樣的事情甚至可能嗎? VC++ 2013說B是不是A的成員從模板類Base <A>衍生出A類,以便Base <A>可以使用A :: B?
我會是這樣的(live example):
template<typename T> struct Impl;
template<typename T> struct Nested;
template <typename T>
class Base
{
private:
typename Nested<T>::type c;
};
struct A;
template<> struct Impl<A> { class B { }; };
template<> struct Nested<A> { using type = typename Impl<A>::B; };
struct A : Base<A>, Impl<A>
{
//...
};
這裏,類Impl
包含A
一部分不依賴於Base
,也就是嵌套類B
。因此A
現在衍生出Base<A>
和Impl<A>
。
類Nested
只包含指定上述嵌套類的別名的別名。現在Base
從Nested
讀取此類型並定義其數據成員,此類型。
在我們專門爲它設計Impl
和Nested
之前,我們需要聲明A
。並且在定義A
之前我們需要這些專業化,因爲此時Base<A>
已實例化,並且這需要Nested<A>
已完成,這又要求Impl<A>
已完成。
從Philip's answer的主要區別是,職責分離多:
Base
沒有得到任何東西,所以有較少的被污染的機會。我們只將其數據成員的類型更改爲typename Nested<T>::type
,就是這樣。
Nested
是一種純粹的性狀特徵。它只定義別名type
,就是這樣。
Impl
是一個實現類。它包含嵌套類B
的定義或可能不依賴於Base
的任何其他內容。
順便說一句,Stroustrup的的The C++ Programming Language第4版有771頁的下面的代碼:
template<typename N>
struct Node_base : N::balance_type { };
template<typename Val, typename Balance>
struct Search_node : Node_base<Search_node<Val, Balance> >
{
using balance_type = Balance;
};
具有完全相同的問題。
謝謝。我會消化這一點,高級模板編程對我來說是一個遙遠的話題。 – NFRCR
故事
如直接在你的問題的意見你正在嘗試簡單地完成規定是不可能的,因爲它是非法的指代不完整類型(其中T = A
在Base
內)。
變通方法
在CRTP的情況下的通用解決方法是使用一個trait
表示成員,應該在兩者Derived
和Base
可用的,但它們並非意在聲明/定義在Base
。
儘管這並不等同於你正在努力完成的任務,但它非常接近它,並且遵循了某種等同的語義。
template<class> struct some_trait; // primary template
template <class T>
struct A : some_trait<T> { // (1)
typename some_trait<T>::C a;
};
template<> struct some_trait<struct B> { // (2)
class C { };
};
struct B : A<B> { // (3)
C b;
};
int
main (int argc, char *argv[])
{
B a; // legal
}
爲什麼解決方法......工作?
把它縮短;我們不再嘗試訪問不完整類型的內部結構。
some_trait<B>
是一個完整的類型其直接的定義(即專業化)標記(2)
後,正因爲如此它可以通過(1)
和(3)
,而不會造成任何問題,可以使用。
你不能,而GCC的錯誤更具描述性,至於爲什麼http://ideone.com/90siYB – StoryTeller
你可以修改哪些類來引入解決方法? – pmr
在你的實際代碼中,B是一個類型還是一個成員變量? –