ich so (live example) gehen würde:
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>
{
//...
};
Hier Klasse Impl
enthält den Teil A
, die nicht auf dem Base
abhängt, das heißt, die verschachtelte Klasse B
. Daher leitet A
jetzt sowohl Base<A>
als auch Impl<A>
ab.
Die Klasse Nested
enthält nur einen Alias, der den Typ der obigen geschachtelten Klasse angibt. Jetzt Base
liest diesen Typ von Nested
und definiert sein Datenelement dieses Typs.
Wir müssen A
erklären, bevor wir Impl
und Nested
dafür spezialisieren. Und wir benötigen diese Spezialisierungen, bevor wir A
definieren, da zu diesem Zeitpunkt Base<A>
instanziiert wird, und dies erfordert, dass Nested<A>
abgeschlossen ist, was wiederum erfordert, dass Impl<A>
abgeschlossen ist.
Der wesentliche Unterschied zu Philip's answer ist, dass die Verantwortlichkeit mehr getrennt sind:
Base
nichts herleiten, so hat weniger Chancen, verunreinigt wird. Wir ändern nur den Typ seines Datenelements in , das ist es.
Nested
ist eine reine Typeigenschaft. Es definiert nur Alias type
, das ist es.
Impl
ist eine Implementierungsklasse. Es enthält die Definition der verschachtelten Klasse B
oder möglicherweise etwas anderes, das nicht von Base
abhängt.
By the way, 4. Auflage von The C++ Programming Language des Stroustrup hat den folgenden Code auf Seite 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;
};
, die genau das gleiche Problem hat.
Sie können nicht, und GCC-Fehler ist aussagekräftiger als warum http://ideone.com/90siYB – StoryTeller
Welche Klassen können Sie ändern, um eine Problemumgehung einzuführen? – pmr
In Ihrem tatsächlichen Code ist B ein Typ oder eine Mitgliedsvariable? –