Variadic templates



  • Finde den Fehler. Ich bin schon fast verzweifelt eben... Nachdem alle Parameter ausgepackt sind, wird f(d...) zu f(). f() ist natürlich definiert, Compiler wollte mir aber nicht glauben.

    #include <iostream>
    using namespace std;
    
    template<typename First, typename... Args>
    void f(First first, Args... d)
    {
    	cout << first << endl;
    	f(d...);
    }
    
    void f() { }
    
    int main()
    {
    	f(2,1,'c');
    }
    

    Das passiert mir nicht nochmal 🙂



  • die Namelookupregeln sind so gestrickt, dass das obere f das untere f nie aufrufen kann, wenn du es nicht vorher deklarierst. Und ADL hilft ja hier auch nicht, wenn du keine Parameter hast.

    Probier mal das hier:

    #include <iostream> 
    using namespace std; 
    
    void f() { } 
    
    template<typename First, typename... Args> 
    void f(First first, Args... d) 
    { 
        cout << first << endl; 
        f(d...); 
    } 
    
    int main() 
    { 
        f(2,1,'c'); 
    }
    


  • Du kannst dein f übrigens auch so implementieren:

    template <typename T> using identity = T;
    
    template<typename... Args>
    void f(Args... d)
    {
      identity<bool[]>{false, (std::cout << d << '\n', false)...};
    }
    
    int main()
    {
        f(2,1,'c');
    }
    

  • Mod

    struct expression_sequence
    {
        template<typename... T>
        expression_sequence(T&&...) {}
    };
    
    template<typename... Args>
    void f(Args... d)
    {
      expression_sequence{std::cout << d << '\n'...};
    }
    
    int main()
    {
        f(2,1,'c');
    }
    

    ist evtl. besser lesbar (basiert auf Absatz 8.5.4/4, der erst nach n3242 eingefügt wurde) - auf die korrekte Klammerwahl ist zu achten! Wenn void-Ausdrücke dabei sind, kommt man allerdings nicht um den Komma-Operator-Trick herum.



  • krümelkacker, mir war schon beim posten die Lösung und das Problem klar. Jedoch wollte ich es auf dem ersten Blick durch die Templates nicht sehen und habe es nur als Hinweis für anderen gepostet.

    void f(int)
    {
      f(); // ja, da schreit mein brain-compiler sofort
    }
    
    void f()
    { }
    
    void g(Args... d)
    {
      g(d...); // hier macht es nicht auf dem ersten blick bling bling
    }
    
    void g()
    { }
    

    Und mit den anderen zwei Anregungen, habe ich soeben meinen Horizont erweitert 🙂


Anmelden zum Antworten