【发布时间】:2019-03-22 15:36:27
【问题描述】:
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>
{
};
【问题讨论】:
-
我知道的不够多,无法回答,但也许
narrow<unsigned>(-1)?static_cast来回可能会产生相同的结果(不确定它是否是 UB)。 -
在我看来,如果它们不是相同的签名并且一个是负数...所以你在 unsigned 和 之间进行转换签名,然后检查签名信息是否丢失?
-
我不知道为什么它是这样写的,但只是看了一眼,我相信你会(正确?错误?)返回“true”以将 -0.0f 转换为整数零,而 MS 实现可能不会针对非整数值进行编译。
标签: c++ c++11 casting narrowing cpp-core-guidelines