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(); }
    };
    

Anmelden zum Antworten