Vererbung & Templateklassen



  • hi,

    Warum ist in folgendem Code der Scope-Operator notwendig? Eigenltich ist doch eindeutig woher obj kommt, oder nicht? Wenn man die Klasse A weglässt, dann funktionierts komischerweise auch ohne den Scope Operator.

    template <typename O>
    class OT
    {
      public:
        void something(){/*bla*/}
    };
    
    class A{};
    
    template <typename I, typename O>
    class B : public A {
      public:
          OT<O> *obj;
    };
    
    template <typename O>
    class B<void, O> : public A {
      public:
          OT<O> *obj;
    };
    
    template <typename O>
    class C : public B<void, O> {
      public:
          void function() {
            //Hier muss B<void, O>::obj->something() stehen
            obj->something();
          }
    };
    

    Der Code ist nicht von mir, also beschwert euch auch nicht, dass man obj in A packen könnte (dann funktionierts auch ohne scope-Operator). :p


  • Mod

    bluecode schrieb:

    ..., dass man obj in A packen könnte (dann funktionierts auch ohne scope-Operator). :p

    nein. abhängige basisklassen werden beim unqualifizierten lookup nicht durchsucht. es ist eben überhaupt nicht klar, das obj ein member der basis B<void, O> ist. das kann erst bei der instantiierung entschieden werden. für zwecke des namelookups ist es auch völlig unerheblich, ob das basisklassentemplate (und evtl. irgendwelche spezialisierungen) bereits definiert wurde.

    was wäre denn z.b., wenn wir nach der definition des templates C noch folgende spezialisierung einführen:

    template <typename O>
    class B<void, O*> {
    public:
        typedef void obj;
    };
    

    ist doch klar, dass obj ein member der basisklasse ist, bzw. in A gefunden wird? wohl kaum...



  • camper schrieb:

    bluecode schrieb:

    ..., dass man obj in A packen könnte (dann funktionierts auch ohne scope-Operator). :p

    nein. abhängige basisklassen werden beim unqualifizierten lookup nicht durchsucht. es ist eben überhaupt nicht klar, das obj ein member der basis B<void, O> ist. das kann erst bei der instantiierung entschieden werden. für zwecke des namelookups ist es auch völlig unerheblich, ob das basisklassentemplate (und evtl. irgendwelche spezialisierungen) bereits definiert wurde.

    Hast recht. War mein Fehler... habs mit dem g++ 3.3.6 versucht und damit ging sogar auch die gepostete Variante. Habs jetzt nochmal mit g++ 4.1.1 versucht und damit geht beides nicht.

    Kann man dann sagen, dass man, wenn man eine Klasse (egal ob die nun template is oder nicht) von nem template ableitet, dass man immer den scope operator braucht? Das scheint dann wohl ein bug im alten g++ (3.3.6) zu sein...


  • Mod

    du kannst nicht von templates ableiten, nur von klassen 😉
    wenn du eine normale klasse von einer templateklasse ableitest, stehen die paramter des basisklassentemplates fest, und die üblichen regeln für namelookup sind in kraft. der begriff "abhängig" stellt ja gerade auf die parameter des zu definierenden templates ab - eine normale klasse hat soetwas nicht.



  • Danke, hat mich zwar einige Zeit zum Überlegen gekostet, aber ich glaub jetzt hab ichs einigermaßen verstanden. 👍


Anmelden zum Antworten