gpt4 book ai didi

c++ - 了解 gsl::narrow 实现

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:33:48 26 4
gpt4 key购买 nike

C++ Core Guidelines有一个 narrow如果类型转换更改值,则抛出。看着 microsoft implementation图书馆:

// 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>(t) != 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;
}

我不明白第二个if .它检查什么特殊情况,为什么不检查 static_cast<U>(t) != u够了吗?


为了完整性:

narrow_cast只是一个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是它的广告:

template <class T, class U>
struct is_same_signedness
: public std::integral_constant<bool,
std::is_signed<T>::value == std::is_signed<U>::value>
{
};

最佳答案

这是检查溢出。让我们看看

auto foo = narrow<int>(std::numeric_limits<unsigned int>::max())

T将是 intU将是 unsigned int .所以

T t = narrow_cast<T>(u);

会给商店-1t .当你把它放回去时

if (static_cast<U>(t) != u)

-1将转换回 std::numeric_limits<unsigned int>::max()所以检查会通过。这不是有效的转换,因为 std::numeric_limits<unsigned int>::max()溢出 int并且是未定义的行为。那么我们继续

if (!details::is_same_signedness<T, U>::value && ((t < T{}) != (u < U{})))

并且由于标志不相同,我们评估

(t < T{}) != (u < U{})

这是

(-1 < 0) != (really_big_number < 0)
== true != false
== true

所以我们抛出一个异常。如果我们走得更远,回过头来使用 so t变为正数,则第二次检查将通过,但第一次检查将失败,因为 t将是正数,并且转换回源类型仍然是相同的正值,不等于其原始值。

关于c++ - 了解 gsl::narrow 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52863643/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com