Ableiten eines Klassentemplates aus einem Klassentemplate
-
Hallo,
ich habe folgende beide Klassentemplates:
template<class C> class abc { private: C* m_container; public: C* container() { return m_container; } }; template<class C> class def : public abc<C> { public: void next() { container(); } };Wenn ich das versuche zu kompilieren, bekomme ich bzgl.
void next() { container(); }die Fehlermeldung
there are no arguments to ‘container’ that depend on a template parameter, so a declaration of ‘container’ must be available
(if you use ‘-fpermissive’, G++ will accept your code, but allowing the use of an undeclared name is deprecated)Ersetze ich allerdings def durch
class def : public abc<int> { public: void next() { container(); } };kann ich kompilieren.
Weiss jemand, was ich hier falsch mache?
-
Das Problem in diesem Fall ist, dass def<> selbst ein Template ist, welches von einem Template erbt. Instanziert wird beides erst bei der Benutzung, so dass zu dem Zeitpunkt der Definition von def<> noch nicht bekannt ist, wie abc<C> aussieht, da ja später noch eine Spezialisierung von abc für ein bestimmtes C auftauchen könnte. Deshalb kann der Compiler erstmal nicht davon ausgehen, dass abc<C> dieselben Member hat, wie das Basistemplate abc<>.
Ist def allerdings selbst kein Template, muss abc<int> vollständig bekannt sein. Dadurch weiss der Compiler auch sicher, ob abc<int> einen Member namens container hat, oder eben nicht.
Die Lösung des Problems ist, den Member der Basisklasse zu qualifizieren, oder über this darauf zuzugreifen:
template<class C> class def : public abc<C> { public: void next() { abc<C>::container(); /* oder */ this->container(); } };