Paramter Packs



  • Hey,
    sagt mal, hat es im Spezifikationsprozess von Variadics irgendeinen Grund gegeben, warum keine Syntax zum Indizieren von Parameterpacks hinzugefügt wurde?
    Ich denke die zwei häufigsten Gründe zum Verwenden von Variadics sind das Wrappen von Aufrufen sowie die Umsetzung von Typlisten zum geordneten Weiterverarbeiten.
    Für den ersten Fall braucht man eigentlich keinen spezielleren Mechanismus, aber der letztere Schreit nach Indizierung von Parameter Packs.

    Jetzt kann man natürlich anführen, dass man die Indizierung einfach über Rekursion umsetzen kann, aber hier kommt der springende Punkt: Das 5. Element rauszufischen bedeutet dann erstmal, dass der Compiler mindestens 5 Templatespezialisierungen entlangrauschen muss, um einen Typ rauszufischen, den er von Anfang an kannte. Das ist doch total beknackt und macht außerdem den Code unleserlich.

    Ich gehe davon aus, dass weite Teile von boost oder ähnlichen Bibliotheken (überall mit traits garnierte policy listen und das ganze Gedöns) X-mal schneller kompiliert würden und 3x leserlicher wären, wenn die Variadic-Syntax das nur zulassen würde.

    Was ist da eure Einstellung zu der Sache?



  • Das geht doch:

    Du kannst einfach in ein tuple packen und dann mit std::get darauf zugreifen. Dass nur statische Zugriffe möglich sind, sollte klar sein.

    template <class... VarArg>
    void foo(VarArg... args)
    {
        std::cout<<std::get<2>(std::make_tuple(args...))<<"\n";
    }
    

    Hier ist nochmal eine übersichtliche Funktion für den Zugriff. Warum die nicht im Standard ist? Keine Ahnung.

    template <std::size_t index, typename... VarArg>
    auto variadic_get(VarArg&&... args)
        -> decltype(std::get<index>(std::make_tuple(args...)))
    {
        return std::get<index>(std::make_tuple(args...));
    }
    
    template <class... VarArg>
    void foo(VarArg... args)
    {
        std::cout<<variadic_get<2>(args...)<<"\n";
    }
    


  • Hallo!
    Also ich sprach ja davon, dass die Problematik eher in Bezug auf Typlisten auftritt, aber davon ab: std::get<...>(...) macht ja im Hintergrund genau dasselbe: Es wandert den Ableitungspfad der N Basisklassen von std::tuple hinab, oder hangelt sich entlang eines Memberbaumes... Genauso wie man das mit Typlisten halt machen würde.
    Wenn ich get< Typliste, 5 >::type hinschreibe, dann sieht das ja auch ganz gut aus, aber der Compiler kommt ins Schwitzen, weil das im Hintergrund eine Template-Rekursion bedeutet, die man eigentlich nie haben wollte, aber verwenden musste, weil die Syntax so schwach ist.



  • Variadic templates verwendet man ja nicht so häufig und wenn doch, dann sind das ja immernoch eine mäßige Anzahl von Parametern.

    Ich kann mir vorstellen, dass tuple und get irgendwann von den Compilern automatisch erkannt und schneller compiled werden. Bis dahin muss man halt mit der erhöhten Zeit auskommen. C++11 ist ja noch neu, da kann man nachsichtig sein.



  • Das fänd' ich irgendwie unschön. Als die Templates damals entworfen wurden, konnte man ja nicht damit rechnen, wofür sie später verwendet würden. Aber in diesem Fall kannte man im Voraus eine Menge Use-Cases. Wenn dann nur die Standard-Typen per später aufgesetztem Compiler-Hack das zur Verfügung haben, was sowieso von Anfang an benötigt wurde, dann weiß ich auch nicht mehr... 😞



  • Marthog schrieb:

    Du kannst einfach in ein tuple packen und dann mit std::get darauf zugreifen. Dass nur statische Zugriffe möglich sind, sollte klar sein.

    template <class... VarArg>
    void foo(VarArg... args)
    {
        std::cout<<std::get<2>(std::make_tuple(args...))<<"\n";
    }
    

    Nein, die Anwendung von make_tuple ist da fehl am Platz.

    -> std::tie



  • DummesPack schrieb:

    Das ist doch total beknackt

    Ja.

    DummesPack schrieb:

    und macht außerdem den Code unleserlich.

    Nicht soooo unleserlich. Man muss das ja nicht selbst implementieren.

    typename tuple_element<tuple<Types...>,index>::type

    Aber das könnte man natürlich mit 'ner besonderen Syntax abkürzen, wie z.B.

    Types[index]

    oder sowas. wir haben ja auch ein sizeof...(Types) und müssen nicht tuple_size<tuple<Types...>>::value schreiben.

    Schreibst du jetzt bitte ein Proposal dafür?
    Danke! 🙂


Anmelden zum Antworten