Ist eine Funktion um einen tuple mit N Elementen zu erzeugen möglich?



  • Hi,

    ich frag mich gerade ob so etwas überhaupt möglich ist

    absoluter dummy code:

    template <std::size_t I, typename T>
    std::tuple< ???  > // i mal T
    function ()
    {
      return make_einen_tuple_mit_I_Ts // ????
    }
    

    also

    auto a = function<3, int> () ;
    

    wäre a der Typ tuple<int, int, int>;

    auto b = function<2, int> () ;
    

    wäre b der Typ tuple<int, int>;

    der frage vorzubeugen wozu man sowas braucht, es geht um Syntax, zB

    auto data = lese<3,int>(datenstream) ;
    

  • Mod

    template <std::size_t I, typename T> 
    constexpr auto function () 
    { 
      if constexpr(I > 0)
        return std::tuple_cat(std::tuple{T{}}, function<I-1, T>());
      else
        return std::tie();
    }
    

    http://melpon.org/wandbox/permlink/8nm478r52JuOWbrQ

    Edit: Du kannst auch einfach std::array<int, 3> verwenden, wird sogar von tuple_ *-Templates unterstützt. Oder einfach vector , und den size_t als Funktionsparameter nehmen.



  • Arcoth schrieb:

    template <std::size_t I, typename T> 
    constexpr auto function () 
    { 
      if constexpr(I > 0)
        return std::tuple_cat(std::tuple{T{}}, function<I-1, T>());
      else
        return std::tie();
    }
    

    http://melpon.org/wandbox/permlink/8nm478r52JuOWbrQ

    Edit: Du kannst auch einfach std::array<int, 3> verwenden, wird sogar von tuple_ *-Templates unterstützt. Oder einfach vector , und den size_t als Funktionsparameter nehmen.

    das schaut toll aus und werd ich in Zukunft so machen.

    jetzt bin ich aber noch etwas auf C++11 (gcc 4.8.2) zwangsbeschränkt

    da habe ich leider keinen auto return type, ich nehme an da muss ich mir mit ->decltype was basteln, oder?
    das if constexpr(I > 0) lässt sich so auch ohne dem constexpr lösen, der rest sollte funktionieren, denke ich.?

    so, leider,

    template <std::size_t I, typename T>
      constexpr auto function ()
      {
        if (I > 0)
          return std::tuple_cat(std::make_tuple(T{}),
              function<I-1, T>());
        else
          return std::tie();
      }
    
    auto iii = node::function<3, int>() ;
    

    bekomm ich super lange Fehle Meldungen mit gcc 4.8.2, richtig lange Fehlermeldungen....



  • Du kannst ein if constexpr nicht einfach durch ein if ersetzen. Vielmehr musst du daraus eine Template-Spezialisierung machen.

    Siehe zum Beispiel https://medium.com/@LoopPerfect/c-17-vs-c-14-if-constexpr-b518982bb1e2 (hab ich jetzt nicht ganz gelesen, aber sieht auf den ersten Blick nach ner guten Erklärung aus)



  • wob schrieb:

    Du kannst ein if constexpr nicht einfach durch ein if ersetzen. Vielmehr musst du daraus eine Template-Spezialisierung machen.

    Siehe zum Beispiel https://medium.com/@LoopPerfect/c-17-vs-c-14-if-constexpr-b518982bb1e2 (hab ich jetzt nicht ganz gelesen, aber sieht auf den ersten Blick nach ner guten Erklärung aus)

    guter Link. Vielen Dank!

    Ja, das ich irgendwie das ganze terminieren muss und dazu eine function<0> oder ähnliches brauche habe ich mir schon gedacht, werde es morgen so probieren.



  • kurze_frage schrieb:

    der frage vorzubeugen wozu man sowas braucht, es geht um Syntax, zB

    auto data = lese<3,int>(datenstream) ;
    

    Wenn N tendenziell klein bleibt würde sich vielleicht die - vermutlich deutlich einfacher zu implementierende - Variante lese<int, int, int>(datenstream) statt lese<3, int>(datenstream) anbieten.



  • Das Wort "lese" gibt es übrigens nicht.


  • Mod

    lies! schrieb:

    Das Wort "lese" gibt es übrigens nicht.

    Bei mir schon. Allerdings nicht als Imperativ.



  • camper schrieb:

    lies! schrieb:

    Das Wort "lese" gibt es übrigens nicht.

    Bei mir schon. Allerdings nicht als Imperativ.

    vielen Danke für den Hinweis, es sollte in der tat 'lies' sein wäre das Interface auch im real-code auf deutsch.
    Leider macht sich langsam bemerkbar das ich seit Jahren nicht mehr im deutschsprachigem Raum lebe. Ich ersuche daher um Nachsicht, sogar um doppelte Nachsicht da meine Deutschkenntnisse aus Wien stammen. (Von da her würde ich lese als Imperativ als gar nicht so falsch ansehen 🙂
    Ich bemühe mich jedoch wirklich in Übung zu bleiben, unter anderem durch die Benutzung dieses Forums.



  • hustbaer schrieb:

    kurze_frage schrieb:

    der frage vorzubeugen wozu man sowas braucht, es geht um Syntax, zB

    auto data = lese<3,int>(datenstream) ;
    

    Wenn N tendenziell klein bleibt würde sich vielleicht die - vermutlich deutlich einfacher zu implementierende - Variante lese<int, int, int>(datenstream) statt lese<3, int>(datenstream) anbieten.

    ja schon, ist aber erstens nicht so elegant, und zweitens würde ich nichts lernen wenn ich den Code so schreib wie ich es schon kann oder es am einfachsten wäre. Zumindest bei Demo und Research Projekten erlaube ich mir den Luxus unbekannte Code-Pfade zu gehen.



  • wenn der Typ bei allen Elementen gleich ist, warum nicht einfach ein std::array?



  • daddy_felix schrieb:

    wenn der Typ bei allen Elementen gleich ist, warum nicht einfach ein std::array?

    auch eine gute Idee, danke!
    ich denke das werde ich machen, nach dem ich jetzt die Tupple Variante habe und weis wie die funktioniert, denke ich das die Array Varainte gar nicht schlecht ist und einige move Operationen einsparen könnte/wird.


Anmelden zum Antworten