Template-Funktions-Spezialisierung in Template-Klasse



  • Hallo,

    ich hab mir eine eigene Klasse gebaut:

    // Sample-Code:
    template<typename BASETYPE>
    class XYZ
    {
      // assign (first, last)
      template<class InputIterator>
      void assign(const InputIterator& first, const InputIterator& last);
    
      // Problem mit dieser Definition
      template<>
      void assign(const MyIterator<BASETYPE>& first, const MyIterator<BASETYPE>& last);
    };
    
    // assign (first, last)
    template<typename BASETYPE>
    template<class InputIterator>
    void XYZ<BASETYPE>::assign(const InputIterator& first, const InputIterator& last)
    {
      size_t n(0);
      for (InputIterator it(first); it!=last; ++it)
      {
        ++n;
      }
      assignCopyReal(n, first, last);
    }
    
    // Problem mit dieser Funktion
    template<typename BASETYPE>
    template<>
    void XYZ<BASETYPE>::assign(const MyIterator<BASETYPE>& first, const MyIterator<BASETYPE>& last)
    {
      if (last.PositionGet() <= first.PositionGet())
      {
        clear();
        return ;
      }
      assignCopyReal((last.PositionGet() - first.PositionGet()), first, last);
    }
    

    Ich bekomme immer den Visual Studio (2008 Pro)-Fehler "C2244: Keine Übereinstimmung für Funktionsdefinition mit vorhandener Deklaration gefunden...", wo er die Funktion

    template<typename BASETYPE>
    template<>
    void XYZ<BASETYPE>::assign(const MyIterator<BASETYPE>& first, const MyIterator<BASETYPE>& last)
    

    meint.

    Auch wenn ich noch ein void XYZ<BASETYPE>::assign< MyIterator<BASETYPE> >(...) daraus mache, mosert er, aber halt vorher noch mit dem Fehler "C2768: Unzulässige Verwendung von expliziten Vorlagenargumenten"

    Ich hab jetzt ca. 2 Stunden lang gegoogelt, aber irgendwie will nichts ordentliches gefunden werden.

    Wie müsste ich die Spezialisierung machen?

    Aufgabe ist:
    In meiner Template-Klasse eine Template-Funktion einzubauen, die "class InputIterator" verarbeitet (z.B. vector<char>). Aber für meinen eigenen Iterator (der Infos enthält, durch die ich schneller arbeiten kann) benötige ich eine Spezialisierung.
    Wie ist die Systax dafür?

    Ich arbeite derzeit mit Visual Studio 2008 Pro, hab aber die 2010er schon bestellt. Trotzdem möchte ich es in beiden Versionen lauffähig haben. Bei meiner Google-Suche habe ich durchaus öfters lesen "dürfen", dass es wohl in Visual Studio ein paar "Sonderfälle" bei Templates gibt. Ist das so einer?

    Danke,
    Stefan



  • Bei dir fehlt die explizite Angabe des Typs bei assign.
    Edit: Oops, da fehlt der namespace. http://stackoverflow.com/questions/3052579/explicit-specialization-in-non-namespace-scope



  • gcc kommt mit einer klareren Fehlermeldung zurück:

    Fehler: explizite Spezialisierung in Gültigkeitsbereich des Nicht-Namensbereiches »class XYZ<BASETYPE>«
    

    Aber glücklicherweise ist die explizite Spezialisierung ja auch gar nicht notwendig. Ich denke mir das etwa so:

    #include <iostream>
    
    template<typename T>
    struct iterator { };
    
    template<typename T>
    struct foo {
      template<typename U> void bar(U const &);
      void bar(iterator<T> const &);
    };
    
    template<typename T> template<typename U>
    void foo<T>::bar(U const &) { std::cout << "T\n"; }
    
    template<typename T>
    void foo<T>::bar(iterator<T> const &) { std::cout << "iterator\n"; }
    
    int main() {
      foo<int> f;
    
      f.bar(2);
      f.bar(iterator<int>());
    }
    

    Kleiner Tip übrigens: Templates sind sehr viel übersichtlicher, wenn man Methoden an Ort und Stelle gleich definiert. Damit spart man sich das ganze template<> template<> template<>-Gewurschtel.



  • Nachtrag:

    Obligatorisch übrigens der Hinweis, dass es sich bei XYZ nicht um eine Template-Klasse handelt, sondern um eine Klassen-Template, d.h. eine Vorlage, aus der sich nach Bedarf Klassen stanzen lassen. Also: XYZ ist eine Klassenvorlage, XYZ<int> ist eine Klasse. Mit Funktionstemplates verhält es sich genauso.



  • template<typename T>
    struct foo {
      template<typename U> void bar(U const &);
      void bar(iterator<T> const &);
    };
    

    In meinem schlauen Buch "C++ von A bis Z" steht allerdings dass man bei überladenen Funktionen wo auch ein Template vorliegt unbedingt ein template<> schreiben muss, weil sonst der Compiler nicht weiß ob er auf das Template oder die Funktion zugreifen soll. Das Ergebnis sei ungewiss.

    Zu:

    template <typename AT>
    struct  A
    {
        template <typename T>
        void foo();
    
        template <>
        void foo<int>();
    };
    
    template <typename AT>
    template<>
    void A<AT>::foo() {}
    // C2244: Keine Übereinstimmung für Funktionsdefinition mit vorhandener Deklaration
    
    template <typename AT>
    template<>
    void A<AT>::foo<int>() {}
    // C2768: Unzulässige Verwendung von expliziten Vorlagenargumenten
    // C3212: Eine explizite Spezialisierung eines Vorlagenmembers muss ein Member einer expliziten Spezialisierung sein
    

    Um meinen Geisteszustand mal klar auszudrücken: Hä???

    Der Hinweis, dass es sich bei XYZ nicht um eine Template-Klasse handelt, sondern um eine Klassen-Template

    Ja, stimmt... wieder mal die Begriffe verwechselt. Der Unterschied ist mir klar. *schäm mich*



  • stefanjann schrieb:

    In meinem schlauen Buch "C++ von A bis Z"

    Das Buch ist nicht schlau, sondern Strohdumm. Wirf es weg.



  • 314159265358979 schrieb:

    Das Buch ist nicht schlau, sondern Strohdumm. Wirf es weg.

    Kritik nehme ich nur an, wenn sinnvolle Argument oder Vorschläge aufgeführt werden:
    Warum ist das Buch "Strohdumm"?
    Welches Buch kann es besser?
    etc etc...
    Aber das sollte in einem extra Thread diskutiert werden.

    Hast du zu meinem Problem eine Meinung/Lösung oder einen Ansatz? Zu der Aussage aus dem Buch eine Meinung/Lösung oder Gegenaussage?



  • Na schön. Argument: Der Autor ist J.W..



  • stefanjann schrieb:

    Aber das sollte in einem extra Thread diskutiert werden.

    Gibt es schon:
    http://www.c-plusplus.net/forum/272350



  • 314159265358979 schrieb:

    Na schön. Argument: Der Autor ist J.W..

    Da ich J.W. nicht kenne, sehe ich das eher als persönliche Meinung deinerseits, was für mich über die Qualität des Buches nichts aussagt.
    Es ist aber nicht das einzige Buch, was mir die Sache mit template<> bestätigt. Ich bin mir nicht ganz sicher, aber im Buch "Die C++ Programmiersprache" von Bjarne Stroupstup schreibt ähnliches. Und den Author wird mal ja wohl nicht in Frage stellen, oder?



  • trolololol



  • 314159265358979 schrieb:

    trolololol

    Selber....
    Hirn einschalten vor solchen Vorwürfen. Nicht jeder, der sich ein J.W.-Buch kauft, erkennt, was da vor ihm liegt. Vor allem Anfänger können nicht erkennen, ob das (ordentliches) C++ ist, was sie da gerade verinnerlichen.



  • stefanjann schrieb:

    314159265358979 schrieb:

    Na schön. Argument: Der Autor ist J.W..

    Da ich J.W. nicht kenne, sehe ich das eher als persönliche Meinung deinerseits, was für mich über die Qualität des Buches nichts aussagt.
    Es ist aber nicht das einzige Buch, was mir die Sache mit template<> bestätigt. Ich bin mir nicht ganz sicher, aber im Buch "Die C++ Programmiersprache" von Bjarne Stroupstup schreibt ähnliches. Und den Author wird mal ja wohl nicht in Frage stellen, oder?

    Pass mal auf. So ungefähr 99% hier im Forum können dir bestätigen, dass C++ von A bis Z nicht gut ist, dass Inhalte sogar manchmal (auch nebenbei) falsch vermittelt werden. Einmal kam sogar ein Typ an, der meinte: "Hey, ich hab mit dem Buch gelernt, mein Code-Stil ist aber gar nicht so schlecht. Seht mal". Hat uns dann was aus seinem letzten Pfojekt gezeigt. z.B. volkards Antwort: "War grad ein viertelstündchen Heulen. Darf sowas nicht jeden Tag machen." Und pumuckl fand auf Anhieb 20 Sachen zum meckern.


  • Mod

    Hacker schrieb:

    stefanjann schrieb:

    314159265358979 schrieb:

    Na schön. Argument: Der Autor ist J.W..

    Da ich J.W. nicht kenne, sehe ich das eher als persönliche Meinung deinerseits, was für mich über die Qualität des Buches nichts aussagt.
    Es ist aber nicht das einzige Buch, was mir die Sache mit template<> bestätigt. Ich bin mir nicht ganz sicher, aber im Buch "Die C++ Programmiersprache" von Bjarne Stroupstup schreibt ähnliches. Und den Author wird mal ja wohl nicht in Frage stellen, oder?

    Pass mal auf. So ungefähr 99% hier im Forum können dir bestätigen, dass C++ von A bis Z nicht gut ist, dass Inhalte sogar manchmal (auch nebenbei) falsch vermittelt werden. Einmal kam sogar ein Typ an, der meinte: "Hey, ich hab mit dem Buch gelernt, mein Code-Stil ist aber gar nicht so schlecht. Seht mal". Hat uns dann was aus seinem letzten Pfojekt gezeigt. z.B. volkards Antwort: "War grad ein viertelstündchen Heulen. Darf sowas nicht jeden Tag machen." Und pumuckl fand auf Anhieb 20 Sachen zum meckern.

    Das ist übrigens dieser Thread, wenn der Link von arghonaut als Argument noch nicht gereicht hat:
    http://www.c-plusplus.net/forum/294532

    @Threadersteller: Nimm 314159265358979 nicht so ernst, der ist so etwas wie der Forenkasper. Wenn du seine dummen Flames ignorierst (und ihm keine Angriffsfläche für ebensolche bietest), findest du gelegentlich sogar eine brauchbare Antwort, insbesondere wenn es um C++11 oder Metaprogrammierung geht.



  • stefanjann schrieb:

    In meinem schlauen Buch "C++ von A bis Z" steht allerdings dass man bei überladenen Funktionen wo auch ein Template vorliegt unbedingt ein template<> schreiben muss, weil sonst der Compiler nicht weiß ob er auf das Template oder die Funktion zugreifen soll. Das Ergebnis sei ungewiss.

    Ungewiss? Der Compiler weiß ziemlich genau, was er machen soll. Allerdings sind die Regeln alles andere als intuitiv, wenn man Funktionstemplate-Spezialisierungen und Überladungen gleichzeitig hat. Aber wofür willst du überhaupt spezialisieren? Du kannst wie bei einer Nicht-Template-Funktion überladen. Um meinen Punkt ein wenig zu untermauern: http://www.gotw.ca/publications/mill17.htm



  • SeppJ schrieb:

    @Threadersteller: Nimm 314159265358979 nicht so ernst, der ist so etwas wie der Forenkasper. Wenn du seine dummen Flames ignorierst (und ihm keine Angriffsfläche für ebensolche bietest), findest du gelegentlich sogar eine brauchbare Antwort, insbesondere wenn es um C++11 oder Metaprogrammierung geht.

    Ich fand es nur lustig, wie der TE nicht ein bisschen an seinem Buch zweifelt. Insbesondere, da nicht nur ich auf dessen Wert hingewiesen habe.



  • 314159265358979 schrieb:

    SeppJ schrieb:

    @Threadersteller: Nimm 314159265358979 nicht so ernst, der ist so etwas wie der Forenkasper. Wenn du seine dummen Flames ignorierst (und ihm keine Angriffsfläche für ebensolche bietest), findest du gelegentlich sogar eine brauchbare Antwort, insbesondere wenn es um C++11 oder Metaprogrammierung geht.

    Ich fand es nur lustig, wie der TE nicht ein bisschen an seinem Buch zweifelt. Insbesondere, da nicht nur ich auf dessen Wert hingewiesen habe.

    Und hier, meine Damen und Herren, sehen wir einen österreichischen C++-Coder, der seine flames zu rechtfertigen versucht. 🙂 🤡



  • Vor allem österreichisch 🙄



  • 314159265358979 schrieb:

    Vor allem österreichisch 🙄

    Du kommst doch aus Wien 😃



  • 314159265358979 schrieb:

    SeppJ schrieb:

    @Threadersteller: Nimm 314159265358979 nicht so ernst, der ist so etwas wie der Forenkasper. Wenn du seine dummen Flames ignorierst (und ihm keine Angriffsfläche für ebensolche bietest), findest du gelegentlich sogar eine brauchbare Antwort, insbesondere wenn es um C++11 oder Metaprogrammierung geht.

    Ich fand es nur lustig, wie der TE nicht ein bisschen an seinem Buch zweifelt. Insbesondere, da nicht nur ich auf dessen Wert hingewiesen habe.

    Ich hab nie geschrieben, dass ich NICHT an dem Buch zweifel, ganz im Gegenteil: schon alleine meine Formulierung "mein schlaues Buch" zeigt doch, dass ich nicht ganz mit dem Inhalt übereinstimme, denn sonst würde ich ja nicht stundenlang googeln müssen und es würde alles funktionieren. Ich kann's nur nicht leiden wenn man einfach ein "...das ist sch****" in den Raum wirft, ohne zu Agumentieren! Dann biete ich auch gerne Angrifsflächen für Flames!
    Ich zähle mich nicht mehr zu den blutigen Anfängern, wohl habe ich aber noch ausreichend Wissenslücken, weil ich viele Dinge einfach noch nie gemacht habe oder noch nie gebraucht habe.
    Ich hab mir natürlich den Thread über Herrn W. durchgelesen und bin schon bei anderen Threads auf die "Ungereimtheiten" des Buches/der Bücher hingewiesen worden. Auch deshalb hab ich das Buch erwähnt, weil ich schon vermutet habe, dass evtl was nicht stimmt. Also mein 314159265358979: so blauäugig wie du meinst bin ich nicht. 😉

    Zurück zum Thema und eigentlichen Problem:
    Wofür brauche ich dann eigentlich das template<> noch, wenn ich doch mit einer Überladung genausoweit komme. Im Visual Studio Manual habe ich das Regelwerk in welcher Reihenfolge die Funktionen gesucht werden gefunden, und ja, es ist alles andere als intuitiv, aber definitiv nicht schwer zu begreifen. Leider habe ich gerade keinen Pc zum testen da, das kann ich erst morgen wieder...ich werd's aber sicherlich morgen früh gleich testen.


Anmelden zum Antworten