variadic template



  • hola leute

    moechte eine funktion mit variabler anzahl an parametern schreiben. das soll vereinfacht so aussehen:

    template<class T, typename... Args>
    int* my_function(const T &var, Args... args)
    {
       static const int count = param_count_of_args(args);
       static int buffer[count];
    
       for(int i = 0; < count;++i)
       {
          buffer[i] = to_string(args[i]).len();
       }
    
       return buffer;
    }
    

    ich brauch also die anzahl der parameter und muss auf die einzelnen parameter zugreifen koennen.
    ich hab leider von den variadics noch ueberhaupt keinen schimmer.

    kanns mir jemand erklaeren ?

    danke

    Meep Meep



    1. sizeof...(Args) // yields amount of parameters.

    2. Quick and Dirty weg: (falscher weg)

    template <typename... List>
    void f (List... params) {
        std::tuple <List...> tup {params...};
        std::cout << std::get <0> (tup) << "\n";
    }
    
    int main()
    {
        f(2);
    }
    

    Es wäre jedoch möglicherweise empfehlenswerter es über quasi Rekursion zu machen.
    EDIT: Und zwar sobald du merkst, dass du mit einer Schleife std::get <i> nicht hinbekommen wirst 😉

    // better use forwarding and &&, but I am lazy to type.

    template <typename Head, typename... Tail>
    void f (Head first, Tail... rest) { 
        // do something with first...
        f <Tail...> (rest...); // now the rest
    }
    
    // Ende der Instanziierungen
    void f() { /* nothing */ }
    


  • Warum dieses komische Konstrukt mit der static Variable? So ginge es viel einfacher und ohne Rekursion:

    template <class... Args>
    std::vector<size_t> my_function(Args... args)
    {
      return { to_string(args).length()... };
    }
    


  • sollte nur pseudo-code sein der zeigt um welche funktionalitaet es mir geht



  • also ich hab da keinen plan wie mir da die rekursion helfen soll.
    bin da hoffnungslos verloren.
    koenntest du mir das bitte erklaeren ?

    danke

    Meep Meep



  • Geht es eigentlich nur darum, die Anzahl der Dezimalstellen von ein paar ints rauszufinden? Wie genau willst du die gewonnenen Werte denn weiterverwenden?



  • dot schrieb:

    Geht es eigentlich nur darum, die Anzahl der Dezimalstellen von ein paar ints rauszufinden? Wie genau willst du die gewonnenen Werte denn weiterverwenden?

    das ist ein reines pseudo beispiel, das verdeutlichen soll , um welche funktionalitaet es mir geht.
    der code ist frei aus der luft gegriffen.

    mir geht es darum das ich die anzahl der arbgumente rausfinde (das weiß ich nun schon) und dann muss ich ueber eine loop mit jedem der unterschiedlichen parameter etwas machen.

    Meep Meep



  • Loopen geht nicht einfach so, du musst die Argumente rekursiv abschälen wie in dem Beispiel von 5cript, d.h. du machst dein Template so, dass du Zugriff auf das erste Argument und den Rest bekommst. Dann kannst du mit dem ersten Argument was tun und den Rest behandelst du, indem du ihn z.B. zurück in das selbe Template leitest, welches dann den nächsten Parameter (ersten Parameter vom Rest) behandelt usw.

    void f();
    
    template <typename Head, typename... Tail>
    void f(Head&& head, Tail&&... tail)
    {
      // do smth with head
    
      f(tail...);  // handle remaining arguments
    }
    
    void f()
    {
      // done
    }
    
    int main()
    {
    }
    


  • somit haben wir ja wieder das problem. ich weiß nicht wie mir die rekursion nuetzlich sein soll. ich muss alle parameter in dem selben funktionsaufruf abarbeiten.
    ansonsten brauch ich die variadic templates nicht. sonst koennte ich das mit
    einer klasse genau so tun:

    meine_klasse klasse;
    klasse(int_var)(string_var)(bool_var)(float_var);
    

    in dem fall haette ich dann den operator() als template gemacht.

    Meep Meep



  • Meep Meep schrieb:

    somit haben wir ja wieder das problem. ich weiß nicht wie mir die rekursion nuetzlich sein soll. ich muss alle parameter in dem selben funktionsaufruf abarbeiten.

    Das geht leider nicht einfach so.

    Meep Meep schrieb:

    ansonsten brauch ich die variadic templates nicht. sonst koennte ich das mit
    einer klasse genau so tun:

    meine_klasse klasse;
    klasse(int_var)(string_var)(bool_var)(float_var);
    

    in dem fall haette ich dann den operator() als template gemacht.

    Und wie genau würdest du damit dann alle Parameter in der selben Funktion bearbeiten? 😉



  • lies mal genau durch. ich hab geschrieben das ich es so machen koennte wenn ich
    nicht auf alle parameter in der selben funktion zugreifen koennen muesste 😉



  • Das Grundproblem ist: Die Parameter haben nicht notwendigerweise alle den selben Typ, damit wird's rein prinzipiell schonmal schwer, die mit einer Schleife zu bearbeiten... 😉



  • Mit C++17 Fold Expressions kann man vieles noch deutlich eleganter gestalten.
    Sich die jetzt schon anzuschauen, mit der Absicht sie zu verwenden, wäre allerdings verfrüht.

    nicht auf alle parameter in der selben funktion zugreifen koennen muesste

    Klingt nach einem Denkfehler für mich. no offense ofc.


Anmelden zum Antworten