templates und Implementierungsvererbung
-
Hallo, ich möchte in der Spezialisierung einer Klasse ein Objekt einer geerbten MemberKlasse erstellen, das gelingt aber nur auf dem Stack.
Weiss jemand wie man das macht ?
So sieht es aus :
template <class T> class A { .... protected: struct Node { .... } .... }template <class T> class B : private A<T> { .... void add(const T& e) { typename A<T>::Node *p; //passt p = new Node; //geht nicht p = new A<T>::Node() //geht nicht .... } .... }
-
1. Was heisst geht nicht?
2. Ganz Standardkonform müsste es so lauten:template<typename> struct Foo { protected: struct Node { }; }; template<typename T> struct Bar : public Foo<T> { void foo() { typename Foo<T>::Node* p = new typename Foo<T>::Node(); delete p; } }; int main() { Bar<int> bar; bar.foo(); return 0; }Also zweimal ein
typename.Grüssli
-
reduzieren und dir ein wenig Tipparbeit sparen kannst du, wenn du B ein privates typedef auf den A::Node spendierst:
template<typename> struct A { protected: struct Node; }; template<typename T> struct B : private A<T> { private: typedef typename A<T>::Node ANode; public: void add(const T&) { ANode* aNode; aNode = new ANode(); /* ... */ } };
-
yeah, dankedieses typename ist dazu da, ne Zweideutigkeit zwischen Typ oder Funktionsaufruf aus der Welt zu schaffen, oder ??
Welche Konstellation müsste den vorherrschen, dass
A<T>::Node *p
ein gültiger Funktionszeiger wäre ?
Irgendwie verstehe ich das nicht so ganz...
-
Runnable schrieb:
yeah, dankedieses typename ist dazu da, ne Zweideutigkeit zwischen Typ oder Funktionsaufruf aus der Welt zu schaffen, oder ??
Welche Konstellation müsste den vorherrschen, dass
A<T>::Node *p
ein gültiger Funktionszeiger wäre ?
Irgendwie verstehe ich das nicht so ganz...die Zweideutigkeit besteht zwischen Subtyp/typedef in A und Member (Funktion oder variable) von A allgemein. Per default geht der Compiler davon aus, dass es sich um ein Member handelt, daher muss man ihm explizit mitteilen dass es ein Typ ist.