Template-Funktion ruft Template-Funktion auf



  • Ich will aus einer Template-Funktion eine andere Template-Funktion aufrufen:

    template<typename T, typename S>
    S* foo() {
     S* res= bar<T,S>();
     ...
     return res;
    }
    
    template <typename T, typename S>
    S* bar() {
     S* res;
     ...
     return res;
    }
    

    Wobei T ein "struct" ist was auch aus nem Template erzeugt wird (falls das ein Problem ist).

    Bitte sagt mir nicht dass das nicht geht, hatte mich so gefreut meine vielen Funktionen los zu sein und das durch Templates zu lösen 😉



  • Klar geht das - der Compiler muß nur an der richtigen Stelle wissen, wie die Funktion bar() aussieht. Die einfache Lösung ist es, die beiden Funktionen zu vertauschen.
    (alternativ reicht auch eine Forward-Deklaration der Funktion bar())



  • Ich habe die Funktionen vertauscht. Der Fehler mit dem Template-Aufruf ist jetzt weg (dafür habe ich jetzt andere "tolle" Fehler). Allerdings war es nicht das Vertauschen, sondern der Parser (von g++ und clang++) kann keine Makros innerhalb von Templates (genauer einen Template-Aufruf) auflösen.

    Als Bsp:

    MAKRO(foo<T,S,basis>());
    

    Das gibt nen Fehler, das man dem Makro zu viele Parameter übergeben hat (und/oder noch andere schöne Fehler).

    Schreibt man allerdings:

    MAKRO((foo<T,S,basis>()));
    

    Funktioniert das ganze. Ich würde das ja als Bug bezeichnen, aber ist bestimmt ein "Feature" bzw. Standardkonform 😉



  • FlashBurn schrieb:

    Ich würde das ja als Bug bezeichnen, aber ist bestimmt ein "Feature" bzw. Standardkonform 😉

    Ich würde es einfach als einen weiteren Beweis ansehen, daß der Präprozessor überschätzt wird 😃
    (der Präprozessor wurde afaik unverändert von C übernommen und hat deshalb keine Ahnung von neuen Features aus C++)



  • CStoll schrieb:

    der Präprozessor wurde afaik unverändert von C übernommen und hat deshalb keine Ahnung von neuen Features aus C++

    Das wäre ja eine Ausrede für g++, aber nicht für clang++! Die bei LLVM hätten das doch wenigstens richtig machen können.



  • Ich rede jetzt nicht vom Präprozessor eines bestimmten Compilers, sondern vom Konzept "Präprozessor", wie es im C++ Standard verwendet wird. Aber hier laufen auch einige Kollegen herum, die den Standard auwendig kennen und dir auf Wunsch genau die Passage zitieren, die das Phänomen beschreibt/erklärt.



  • Das ist dann ja Fail-By-Design 😉



  • Der Präprozessor funktioniert ganz einfach: Er erkennt Kommas als Separatoren zwischen den einzelnen Argumenten. Da die Template-Syntax mit den spitzen Klammern zur Präprozessorzeit noch keine Bedeutung hat, wird sie ignoriert.

    Zum Beispiel könnte auch jemand auf die Idee kommen, Operatoren zu übergeben. Und warum sollte

    MAKRO(<, >)
    

    sich anders verhalten als

    MAKRO(a, b)
    

    ? Durch zusätzliche Klammerung mit () kannst du den Präprozessor allerdings darauf hinweisen, dass damit nur ein Argument gemeint ist. Aber das funktioniert nicht immer. Mit C++0x und Variadic Macros gibt es ein paar Situationen mehr, die funktionieren.


Anmelden zum Antworten