Template-Parameter an Basisklasse "weiterleiten"



  • Mahlzeit,

    folgender Code will sich nicht kompilieren lassen, und ich bin etwas ratlos, wo dabei das Problem liegen könnte:

    template<typename T>
    class Foo {
      protected:
        int _x;
    };
    
    template<typename T>
    class Bar : public Foo<T> {
      public:
        Bar(int x) { _x = x; }
    };
    

    g++ sagt dazu:

    foo.cc: In constructor ‘Bar<T>::Bar(int)’:
    foo.cc:10: error: ‘_x’ was not declared in this scope

    Wie kommt der auf sowas? 😉

    Interessanterweise funktioniert das ganze, sobald ich entweder aus Foo oder aus Bar eine normale, "nicht-Template"-Klasse mache. Ich denke, irgendwas übersehe ich hier, aber was?

    Danke



  • Benutz' Foo<T>::_x. Du musst halt ein wenig expliziter werden, damit der Compiler das schluckt.



  • Das liegt an der Namensauflösung bei Templates. Kannst ja mal die Suche bemühen, das Thema taucht öfter auf.

    Beheben kannst du dein Problem wie folgt:

    // Variante #1
    template<typename T>
    class Bar : public Foo<T> {
      using Foo<T>::_x;
      public:
        Bar(int x) { _x = x; }
    };
    
    // Variante #2
    template<typename T>
    class Bar : public Foo<T> {
      public:
        Bar(int x) { Foo<T>::_x = x; }
    };
    
    // Variante #3
    template<typename T>
    class Bar : public Foo<T> {
      public:
        Bar(int x) { this->_x = x; }
    };
    


  • Danke euch beiden, das hilft weiter!

    Macht es Sinn zu fragen, warum das so ist? Mir will nämlich beim besten Willen kein Grund dafür einfallen...



  • Denk dir folgendes Beispiel durch wenn du wissen willst wieso das Sinn macht:

    template <class T> class base;
    
    template <> class base<int>
    {
    protected:
        int a;
    };
    
    template <> class base<short>
    {
    };
    
    int a;
    
    template <class T> class derived : public base<T>
    {
    public:
        derived()
        {
            a = 123; // welches a bin ich?
        }
    };
    


  • Oha... Ja, das macht Sinn. Wenn auch auf eine etwas seltsame Art und Weise, wie das wohl nur C++ kann 🙄


Anmelden zum Antworten