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).