Namenswahl Basisklasse und abgeleitete Template-Klasse



  • Ich hab mal das Problem einer etwas anderen Art!
    Und zwar habe ich hier eine Kombination von Basis und abgeleiteten Template-Klassen, mit denen man sozusagen gleichberechtigt rumhantieren kann. Nun hätte ich mir natürlich gewünscht, dass man der Basisklasse den selben Namen wie den Templates verpassen könnte (schließlich ergeben die template-namen ja nur mit angehängtem parameter einen Typ), leider geht das aber nicht. Fällt euch da irgendein Trick ein? Ist das aus einem bestimmten Grund eine total schlechte Idee?

    Viele Grüße,
    Michael



  • Decimad schrieb:

    Ich hab mal das Problem einer etwas anderen Art!
    Und zwar habe ich hier eine Kombination von Basis und abgeleiteten Template-Klassen, mit denen man sozusagen gleichberechtigt rumhantieren kann. Nun hätte ich mir natürlich gewünscht, dass man der Basisklasse den selben Namen wie den Templates verpassen könnte (schließlich ergeben die template-namen ja nur mit angehängtem parameter einen Typ), leider geht das aber nicht. Fällt euch da irgendein Trick ein? Ist das aus einem bestimmten Grund eine total schlechte Idee?

    Viele Grüße,
    Michael

    Das geht nicht direkt. Das würde ja der ODR widersprechen.
    Du könntest Deine Basisklasse aber (natürlich mit einem vom Template unterschiedlichen Namen) in eine Spezialiserung Deines Templates für den in der Basisklasse benutzten Typen wrappen.



  • Tachyon schrieb:

    Du könntest Deine Basisklasse aber (natürlich mit einem vom Template unterschiedlichen Namen) in eine Spezialiserung Deines Templates für den in der Basisklasse benutzten Typen wrappen.

    bzw. wenn in der Basisklasse noch keine Typspezifischen Dinge geschehen spezialisierst du das template für void, und das allgemeine Template leitest du davon ab:

    template <typename T = void>
    class Foo; //nur forward-decl, da die allgemeine Version zuerst die Spezialisierung braucht.
    
    template<>
    class Foo<void>
    {
    public:
       virtual void bla() {cout << "bla" << endl; }
    };
    
    template <typename T>
    class Foo : public Foo<void>
    {
       T t;
    public:
       Foo(T const& t) : t(t) {}
       virtual void bla() {cout << "bla: " << t << endl; }
    };
    
    Foo<>* make_Foo() {return new Foo<>();}
    
    template<typename T>
    Foo<T>* make_Foo(T const& t) {return new Foo<T>(t);}
    
    int main()
    {
       Foo<>* fptrs[3];
    
       fptrs[0] = make_Foo(15);    //Foo<int>
       fptrs[1] = make_Foo();      //Foo<void>
       fptrs[2] = make_Foo(12.55); //Foo<double>
    
       for(int i = 0; i < 3; ++i)
       {
          fptrs[i]->bla();
          delete fptrs[i];
       }
    }
    


  • Danke für eure Antworten!
    pumuckl, das was du da so schön gepostest hast, hatte ich mir dann auch mal durch den Kopf gehen lassen, aber fand die Klammern im Geiste unschön. Jetzt, wo ich das bei dir sehe, frage ich mich, ob das nicht auch viel besser den Umgang mit den Typen darstellt.
    value<> der unspezialisierte und value<int> der spezialisierte Fall sieht ja eigenlich doch ganz gut aus und drückt ohne Anhang von "base" oder soetwas eine unspezifizierte Sache aus! Vielleicht würde ich dann anstatt void eine struktur wie "generic" oder soetwas nehmen, aber der Vorschlag sieht doch viel besser aus, als ich gedacht hatte! Manchmal sollte man nicht im Geiste schon alles verwerfen 😃

    Danke euch nochmal!
    Michael



  • Decimad schrieb:

    Vielleicht würde ich dann anstatt void eine struktur wie "generic" oder soetwas nehmen, aber der Vorschlag sieht doch viel besser aus, als ich gedacht hatte!

    Natürlich kannst du ein leeres struct mit irgendeinem sprechenden Namen definieren um deine Basisklasse zu kennzeichnen - das kommt dann vermutlich bei Compilermeldungen noch besser raus als ein simples void.

    struct TheMotherOfAllWeapons {};
    
    template <typename T = TheMotherOfAllWeapons>
    class Weapon;
    
    template <>
    class Weapon<TheMotherOfAllWeapons>
    {
    public:
      void boom() { cout << "We will be generous." << endl; }
    };
    
    //usw...
    

Anmelden zum Antworten