Ansicht umschalten
Avatar von pre alpha
  • pre alpha

mehr als 1000 Beiträge seit 13.05.2006

unsauber

Hallo Rainer,
mir scheint der Beitrag mit heiĂźer Nadel gestrickt zu sein, da sich gleich mehrere Fehler eingeschlichen haben.

template <typename T> auto get_value(T t) { if constexpr (std::integral<T>) // (1) return *t; // deduces return type to int for T = int* else // (2) return t; // deduces return type to int for T = int }

Was hat std::integral<T> mit Dereferenzierung zu tun? Das es im Standard kein Concept Pointer oä gibt müßte man dies nachrüsten:

template <typename Type> concept pointer = std::is_pointer_v<Type>; template <typename Type> concept dereferencable = requires(Type t) { *t; }; template <typename T> constexpr decltype(auto) get_value(const T& t) noexcept { //if constexpr (pointer<T>) return *t; if constexpr (dereferencable<T>) return *t; else return t; }

Bei den Templates fehlt die PrĂĽfung auf N>=0 (da int) und fĂĽr Factorial die Spezialisierung fĂĽr 0 und im else-Zweig der Funktion factorial muĂź 1 zurĂĽckgegeben werden und nicht N; richtig:

template <int N> requires (N >= 0) struct Factorial { static constexpr int value = N * Factorial<N-1>::value; }; template <> struct Factorial<1> { static constexpr int value = 1; }; template <> struct Factorial<0> { static constexpr int value = 1; }; template <int N> //requires (N >= 0) constexpr int factorial() noexcept { static_assert(N >= 0, "negativ"); if constexpr (N >= 2) return N * factorial<N-1>(); else return 1; }

Nun könnte man die gleich auf unsigned umschreiben da negative Werte unzulässig sind

template <unsigned N> struct Factorial_U { static constexpr unsigned value = N * Factorial_U<N-1>::value; }; template <> struct Factorial_U<1> { static constexpr unsigned value = 1; }; template <> struct Factorial_U<0> { static constexpr unsigned value = 1; }; template <unsigned N> constexpr unsigned factorial_u() noexcept { if constexpr (N >= 2) return N * factorial_u<N-1>(); else return 1; }

aber das hat einen unschönen Nebeneffekt:
factorial<20>() und Factorial<20>::value schmeiĂźen korrekt einen Ăśberlauffehler,
factorial_u<20>() und Factorial_U<20>::value dagegen nicht.

Last but not least kann man die Fakultät auch so berechnen:

template <typename Type> constexpr auto factorial(const Type& arg) noexcept { return std::tgamma(arg + 1); }

(bekommt natĂĽrlich ein FP-Ergebniss).

thx
pre alpha

Edit
hatte selber nen Bug drinne -> entfernt

Das Posting wurde vom Benutzer editiert (14.02.2022 13:06).

Bewerten
- +
Ansicht umschalten