Das C++ Core-Richtlinien hat ein narrow
Cast, der wirft, wenn der Cast den Wert ändert. Mit Blick auf die Microsoft-Implementierung der Bibliothek:
// narrow() : a checked version of narrow_cast() that throws if the cast changed the value
template <class T, class U>
T narrow(U u) noexcept(false)
{
T t = narrow_cast<T>(u);
if (static_cast<U>
gsl::details::throw_exception(narrowing_error());
if (!details::is_same_signedness<T, U>::value && ((t < T{}) != (u < U{}))) // <-- ???
gsl::details::throw_exception(narrowing_error());
return t;
}
Das zweite verstehe ich nicht if
. Auf welchen Sonderfall wird geprüft und warum nicht static_cast<U>
Zur Vollständigkeit:
narrow_cast
ist nur ein static_cast
:
// narrow_cast(): a searchable way to do narrowing casts of values
template <class T, class U>
constexpr T narrow_cast(U&& u) noexcept
{
return static_cast<T>(std::forward<U>(u));
}
details::is_same_signdess
ist, was es bewirbt:
template <class T, class U>
struct is_same_signedness
: public std::integral_constant<bool,
std::is_signed<T>::value == std::is_signed<U>::value>
{
};
Ich weiß nicht genug, um darauf eine Antwort zu geben, aber vielleicht
narrow<unsigned>(-1)
? EINstatic_cast
hin und her würde wahrscheinlich das gleiche Ergebnis liefern (nicht sicher, ob es UB ist oder nicht).– Kevin
17. Oktober 2018 um 21:12 Uhr
Es sieht für mich so aus wenn sie nicht die gleiche Vorzeichenhaftigkeit haben und eine negativ ist ... also wirfst du dazwischen ohne Vorzeichen und unterzeichnet dann wird geprüft, ob Schild Informationen gehen verloren?
– Galik
17. Oktober 2018 um 21:24 Uhr
Ich weiß nicht genau, warum es so geschrieben ist, aber wenn ich nur einen Blick darauf werfe, glaube ich, dass Ihr (richtig? falsch?) "true" zurückgibt, um -0.0f in eine ganzzahlige Null umzuwandeln, während die MS-Implementierung dies wahrscheinlich nicht tut für nicht ganzzahlige Werte kompilieren.
– Tschu
17. Oktober 2018 um 21:28 Uhr