Ungültige Funktionsargumente behandeln, ja oder nein?


  • Mod

    Hier was ideone-Compatibles

    #include <cstdint>
    #include <limits>
    #include <array>
    #include <cassert>
    #include <cstddef>
    
    template <typename T, unsigned N> struct cfak
    { static const T value = T(-1) / N < cfak<T, N-1>::value ? 0 : N * cfak<T, N-1>::value; };
    template <typename T> struct cfak<T, 0>
    { static const T value = 1; };
    
    template <typename T, unsigned N = 0, bool = cfak<T, N>::value == 0>
    struct max_calculable
    { static const unsigned value = max_calculable<T, N+1>::value; };
    template <typename T, unsigned N>
    struct max_calculable<T, N, true>
    { static const unsigned value = N; };
    
    template <std::size_t... i> struct indexes;
    template <std::size_t N, typename = indexes<>> struct make_indexes;
    template <std::size_t N, std::size_t... i> struct make_indexes<N, indexes<i...>>
    { typedef typename make_indexes<N-1, indexes<0, (i+1)...>>::type type; };
    template <std::size_t... i> struct make_indexes<0, indexes<i...>>
    { typedef indexes<i...> type; };
    
    template <typename T, typename = typename make_indexes<max_calculable<T>::value>::type>
    struct fakTable;
    
    template <typename T, std::size_t... i>
    struct fakTable<T, indexes<i...>>
    { static const T values[sizeof...(i)]; };
    
    template <typename T, std::size_t... i>
    const T fakTable<T, indexes<i...>>::values[sizeof...(i)] = { cfak<T, i>::value... };
    
    unsigned long long fak(uint8_t n)
    {
      assert(n < max_calculable<unsigned long long>::value);
      return fakTable<unsigned long long>::values[n];
    }
    
    #include <iostream>
    using std::cout;
    
    int main()
    {
      cout << fak(1) << '\n';
      cout << fak(5) << '\n';
      cout << fak(10) << '\n';
      cout << fak(11) << '\n';
      cout << fak(12) << '\n';
      cout << fak(21) << '\n';
      cout << fak(22) << '\n';
    }
    


  • Die Mehrzahl von 'index' ist 'indices' :p





  • pumuckl schrieb:

    unsigned long long fak(uint8_t n)
    {
      typedef typename fakTable<0>::type table;
      assert(n < table::Nmax);
      return table::values[n];
    }
    

    Wieso nicht uint64_t als Rückgabetyp, pumuckl?



  • Gugelmoser schrieb:

    pumuckl schrieb:

    unsigned long long fak(uint8_t n)
    {
      typedef typename fakTable<0>::type table;
      assert(n < table::Nmax);
      return table::values[n];
    }
    

    Wieso nicht uint64_t als Rückgabetyp, pumuckl?

    👍
    Hab ich gar nicht dran gedacht.
    Mach aber lieber** uint_least64_t **draus.



  • Gugelmoser schrieb:

    pumuckl schrieb:

    unsigned long long fak(uint8_t n)
    {
      typedef typename fakTable<0>::type table;
      assert(n < table::Nmax);
      return table::values[n];
    }
    

    Wieso nicht uint64_t als Rückgabetyp, pumuckl?

    Weil long long mindestens(!) 64 Bit hat. Wurde mit C++11 in den Standard aufgenommen.



  • Cyres schrieb:

    Weil long long mindestens(!) 64 Bit hat. Wurde mit C++11 in den Standard aufgenommen.

    Ah mindestens. 🤡 Demnach ist es also schnuppe, ob unsigned long long oder uint_least64_t .



  • Gugelmoser schrieb:

    Cyres schrieb:

    Weil long long mindestens(!) 64 Bit hat. Wurde mit C++11 in den Standard aufgenommen.

    Ah mindestens. 🤡 Demnach ist es also schnuppe, ob unsigned long long oder uint_least64_t .

    Trotzdem ist es deutlich besser, direkt zu schreiben, worum es einem bei einem Skalar geht.
    Wenn man int_least64_t schreibt, weiß der Leser sofort, was für Anforderungen der Datentyp zu entsprechen hat.



  • Sone schrieb:

    [Trotzdem ist es deutlich besser, direkt zu schreiben, worum es einem bei einem Skalar geht.
    Wenn man int_least64_t schreibt, weiß der Leser sofort, was für Anforderungen der Datentyp zu entsprechen hat.

    Deswegen wollte ich pumuckl fragen, wieso er beim Parameter den C++11 Typen nimmt, beim Rückgabetyp jedoch nicht. 😉



  • Gugelmoser schrieb:

    Sone schrieb:

    [Trotzdem ist es deutlich besser, direkt zu schreiben, worum es einem bei einem Skalar geht.
    Wenn man int_least64_t schreibt, weiß der Leser sofort, was für Anforderungen der Datentyp zu entsprechen hat.

    Deswegen wollte ich pumuckl fragen, wieso er beim Parameter den C++11 Typen nimmt, beim Rückgabetyp jedoch nicht. 😉

    Ahhh.... 😃 🙂



  • Cyres schrieb:

    Weil long long mindestens(!) 64 Bit hat. Wurde mit C++11 in den Standard aufgenommen.

    Das überrascht mich jetzt.
    Ich kann's aber nicht finden. Wo steht das?

    Danke,
    FW



  • Furble Wurble schrieb:

    Cyres schrieb:

    Weil long long mindestens(!) 64 Bit hat. Wurde mit C++11 in den Standard aufgenommen.

    Das überrascht mich jetzt.
    Ich kann's aber nicht finden. Wo steht das?

    Danke,
    FW

    www.gidf.de 😉
    2 Sekunden: http://en.wikipedia.org/wiki/C%2B%2B11#Type_long_long_int



  • Cyres schrieb:

    Furble Wurble schrieb:

    Cyres schrieb:

    Weil long long mindestens(!) 64 Bit hat. Wurde mit C++11 in den Standard aufgenommen.

    Das überrascht mich jetzt.
    Ich kann's aber nicht finden. Wo steht das?

    Danke,
    FW

    www.gidf.de 😉
    2 Sekunden: http://en.wikipedia.org/wiki/C%2B%2B11#Type_long_long_int

    Lass mich meine Frage umformulieren: "Wo steht das im Standard?"



  • Furble Wurble schrieb:

    Das überrascht mich jetzt.
    Ich kann's aber nicht finden. Wo steht das?

    Gute Frage, ich kann es auch nicht finden. Das einzige, das ich finde, ist:

    There are five standard signed integer types : “signed char”, “short int”, “int”, “long int”, and “long
    long int”. In this list, each type provides at least as much storage as those preceding it in the list.

    CHAR_BIT Angaben zu den einzelnen Typen finde ich auch keine.



  • Die Wertebereiche stehen im C99-Standard, auf den sich C++11 bezieht.



  • Bashar schrieb:

    Die Wertebereiche stehen im C99-Standard, auf den sich C++11 bezieht.

    Ja - jetzt hab ich's auch. 🙂

    18.3.3 Climits
    besagt das in climits das gleiche wie in limits.h steht.

    Und in limits.h (c99/5.2.4.2 Numerical limits) stehen 64 bittige Bereiche für LLONG_MAX, LLONG_MIN, ULLONG_MAX.

    Hmmm...fast ein bißchen schade, dass es nicht mehr so allgemein gehalten ist...



  • Furble Wurble schrieb:

    Bashar schrieb:

    Die Wertebereiche stehen im C99-Standard, auf den sich C++11 bezieht.

    Ja - jetzt hab ich's auch. 🙂

    18.3.3 Climits
    besagt das in climits das gleiche wie in limits.h steht.

    Und in limits.h (c99/5.2.4.2 Numerical limits) stehen 64 bittige Bereiche für LLONG_MAX, LLONG_MIN, ULLONG_MAX.

    Hmmm...fast ein bißchen schade, dass es nicht mehr so allgemein gehalten ist...

    Japs, etwas versteckt das Ganze.



  • Furble Wurble schrieb:

    Hmmm...fast ein bißchen schade, dass es nicht mehr so allgemein gehalten ist...

    Was wie allgemein (*auf dem Schlauch steh*) 😕
    Meinst du dass ein Mindestbereich für bestimmte Typen vorgeschreiben ist? Falls ja, was soll daran bitte schade sein? Ich sehe das klar als Vorteil.



  • Gugelmoser schrieb:

    Deswegen wollte ich pumuckl fragen, wieso er beim Parameter den C++11 Typen nimmt, beim Rückgabetyp jedoch nicht. 😉

    Weil pumuckl auf Sones Code aufgesetzt hatte, der genau das macht. Aber Camper hats eh gerockt, ich geh mich schämen 😉



  • hustbaer schrieb:

    Furble Wurble schrieb:

    Hmmm...fast ein bißchen schade, dass es nicht mehr so allgemein gehalten ist...

    Was wie allgemein (*auf dem Schlauch steh*) 😕
    Meinst du dass ein Mindestbereich für bestimmte Typen vorgeschreiben ist? Falls ja, was soll daran bitte schade sein? Ich sehe das klar als Vorteil.

    Ich meinte die schon von Gugelmoser zitierte Garantie aus früheren Versionen von C++.

    There are five standard signed integer types : “signed char”, “short int”, “int”, “long int”, and “long long int”. In this list, each type provides at least as much storage as those preceding it in the list.

    Meiner Erfahrung nach, war das allerdings auch häufig Quelle für Diskussionen und vielleicht auch Fehler. Jetzt rückt der Standard näher an Vermutungen von Programmieranfängern und erspart allen das Nachschlagen in der Compilerdokumentation, bzw. numeric_limits<...>::max() und Konsorten.

    Also wohl eine gute Sache.

    Wobei mir die Diskussionen fehlen werden... 🙂


Anmelden zum Antworten