Partielle Template Spezifizierung und Deklarationsproblem



  • Hallo
    Ich probiere gerade mit Typelists herum und habe dazu folgenden interessanten Artikel gefunden:
    http://www.ddj.com/cpp/184403813

    Mein Problem bezieht sich auf die partielle Template Spezifikation - ich versuche folgenden Code zu benutzen:

    template <class T1>
    struct cons<T1, null_typelist, null_typelist,
        null_typelist>
    {
        typedef typelist<T1, null_typelist> type;
    };
    
    template <class T1, class T2>
    struct cons<T1, T2, null_typelist, null_typelist>
    {
        typedef typelist<T1, typelist<T2,
            null_typelist> > type;
    };
    
    template <class T1, class T2, class T3>
    struct cons<T1, T2, T3, null_typelist>
    {
        typedef typelist<T1, typelist<T2, typelist<T3,
            null_typelist> > > type;
    };
    
    template <class T1, class T2, class T3, class T4>
    struct cons
    {
        typedef typelist<T1, typelist<T2, typelist<T3, 
            typelist<T4, null_typelist> > > > type;
    };
    

    ...dabei meckerte mein g++ erstmal, deshalb hab ich noch eine allgemeine Deklaration der struct vorangestellt:

    template <class T1, class T2, class T3, class T4> struct cons;
    

    ...nun versuche ich an anderer Stelle weiter unten folgenden Aufruf:

    typedef cons< unsigned int >::type MyUintTestList;
    

    Dabei wird nun folgendes angemeckert:

    (Zeile: Aufruf von cons)
    error: wrong number of template arguments (1, should be 4)
    (Zeile: Meine vorangestellte Deklaration von cons)
    error: provided for "template<class T1, class T2, class T3, class T4> struct cons"
    (Zeile: Aufruf von cons)
    error: expected ";" before "MyUintTestList"
    

    Ich denke irgendwie fehlt etwas an der Deklaration der verschiedenen partiellen Template Spezifikationen, aber ich komm irgendwie nicht drauf. Ich habe auch schon die "fehlenden Template-Stellen" im Aufruf durch NullTypes (im obigen Bsp: "null_typelist" zu ersetzen - erfolglos!).

    Frage:
    Wie muss ich das Deklarieren, damit ich obige Errors nicht bekomme (liefere gerne mehr Code, wenn die Beschreibung so nicht reicht)?
    😕



  • Hmm. Hast du auch die nester Version des g++?



  • Danke, aber.. was ist denn die "nester Version des g++"?? Flags? Ich nutze Debian - ist da ein zusaetzliches Paket noetig?



  • Fabeltier schrieb:

    Danke, aber.. was ist denn die "nester Version des g++"?? Flags? Ich nutze Debian - ist da ein zusaetzliches Paket noetig?

    😮 .. Sorry. ich meinte neuste.. 😉

    Also sprich 4.3.2

    http://gcc.gnu.org/



  • Ah, ok.. nvm

    g++ (Debian 4.3.2-1) 4.3.2
    

    Daran sollte es also eigentlich nicht liegen und obige Frage bleibt offen. 😞



  • Hast du auch null_typelist definiert?



  • Fellhuhn schrieb:

    Hast du auch null_typelist definiert?

    Ja, die Namen sind bei mir etwas anders, also.. der NullType heisst bei mir NullType:

    class NullType{};
    

    Ich glaube in dem Artikel ist der NullType genauso definiert.



  • Fabeltier schrieb:

    Fellhuhn schrieb:

    Hast du auch null_typelist definiert?

    Ja, die Namen sind bei mir etwas anders, also.. der NullType heisst bei mir NullType:

    class NullType{};
    

    Ich glaube in dem Artikel ist der NullType genauso definiert.

    Das heißt was in deinem ersten Posting steht ist nicht dein Code? Auf den ersten Blick würde ich nämlich sagen das du dann vermutlich dich irgendwo einfach vertippt hast.



  • LOL, tja wuerde ich zunaechst auch sagen.. 😉

    Nur, "mein Code" ist etwas umfassender - ich wollte eigentlich mit den Typelists herumspielen, ich stolpere aber schon bei der Deklaration der Partiellen Templates bzw den "richtigen" Forward Deklarationen (laut Fehlermeldungen bin ich mir hier sehr sicher dass es daran liegt, ich weiss eben nur nicht wie's geht).

    Ich habe obigen Code aus dem Artikel auch ausprobiert - so ist's ja nicht! - aber mit selber Fehlermeldung. Oder besser gesagt - bekam ich eine andere Meldung "cons ist kein Template". Das heisst fuer mich eindeutig, dass ich vor der Partiellen Template Spezifizierung erstmal das "normale Template" mit ALLEN Templatetypen zumindest einmal deklarieren muss (wie im 1. Posting schon beschrieben). Darauf wird in dem Artikel nicht eingegangen und den Fehler kannte ich schon, tja und daraufhin bekam ich eben die besagten 3 Fehlermeldungen pro Aufruf (eigentlich auch im 1. Posting schon beschrieben).

    Dh, irgendwie scheint die Forward Declaration nicht ganz vollstaendig zu sein - der Compiler liest nur die erste und meint dann beim lesen des Aufrufs.. "ehh pah, da fehlen noch x Typen bei dem Aufruf! -> Error 1: zu wenig Typen, Error 2: vllt auch zu viele deklariert und Error 3: irgendwas fehlt da einfach vorm ';' damit's stimmt!!". Tja, aber wie geht's dann?


  • Administrator

    Also so, wie es im Artikel steht, geht es bei mir auch nicht. Allerdings wenn man das ein wenig umformuliert und mit den eigenen Templatekenntnissen versieht, dann sollte das folgende funktionieren (Bei mir kompiliert er es jedenfalls):

    template <class H, class T>
    struct typelist
    {
    	typedef H head;
    	typedef T tail;
    };
    
    class null_typelist { };
    
    // Das hier muss als erstes hin, beim Artikel als letztes drin.
    // Zudem Defaulttypen setzen.
    template <class T1, class T2 = null_typelist, class T3 = null_typelist, class T4 = null_typelist> 
    struct cons
    { 
    	typedef typelist<T1, typelist<T2, typelist<T3, typelist<T4, null_typelist> > > > type; 
    };
    
    template <class T1> 
    struct cons<T1, null_typelist, null_typelist, null_typelist> 
    { 
    	typedef typelist<T1, null_typelist> type; 
    }; 
    
    template <class T1, class T2> 
    struct cons<T1, T2, null_typelist, null_typelist> 
    { 
    	typedef typelist<T1, typelist<T2, 
    		null_typelist> > type; 
    }; 
    
    template <class T1, class T2, class T3> 
    struct cons<T1, T2, T3, null_typelist> 
    { 
    	typedef typelist<T1, typelist<T2, typelist<T3, null_typelist> > > type; 
    }; 
    
    int main()
    {
    	typedef cons<unsigned int>::type type;
    
    	return 0;
    }
    

    Sonstige Veränderungen, ausser die beim Kommentar, wurden nicht gemacht.

    Grüssli



  • Super,

    Es kompiliert druch. Ich fass das nochmal zusammen:
    1. keine Forward Deklaration
    2. die Definition der "vollstaendigen" template Klasse zuerst
    3. fuer jeden template Parameter (ausser dem ersten natuerlich) einen Default Template Parameter setzen (den Null Type)

    Das ganze bezieht sich auf die Typlisten aus Alexandrescu's "Modern C++ Design". Leider werden dort (und in Loki) die Typlisten nur ueber Macros angesprochen, in dem spaeter veroeffentlichten Artikel (Link) beschreibt er eben diese, hier diskutierte, Zugriffsmethode.

    Danke nochmal!! 🙂


Anmelden zum Antworten