Boost或标准库是否提供了一种检查演员阵容是否无损的方法

Does Boost or the Standard Library provide a way to check whether a cast is lossless?

本文关键字:是否 检查 方法 一种 标准 Boost      更新时间:2023-10-16

我正在寻找一个标准库或Boost函数,它可以将数字无损地转换为另一个基元类型,并以某种方式通知我转换是否无损(如果不是,则抛出异常)。以下是一些例子:

auto x = lossless_cast<double>(1u); // ok, double can represent 1
auto x = lossless_cast<int>(1.2); // fail, int can't represent 1.2
auto x = lossless_cast<int>(1E200); // fail, int can't represent 1E200

boost::numeric_cast的接近之处在于,它会拾取超出目标类型数值范围的强制转换,但如果它们是无损的,则不会拾取,而是在目标类型内的(请参阅我的第二个示例)。

C语言有一个SO问题,它为这个问题提供了一些手工解决方案,但我正在寻找boost或标准库解决方案,基本上具有以下功能:

template <typename out, typename in>
out lossless_cast(in in_value)
{
out out_value = static_cast<out>(in_value);
if (static_cast<in>(out_value) != in_value)
throw; // some exception
return out_value;
}

是否存在此功能?

我很确定Standard中没有预先推出任何内容,也不知道boost中有任何内容,但它是一个大库。任何使用强制转换的实现都必须小心未定义的行为,以防超出4.9[conv.pint]的范围值,但由于boost::numeric_cast<>表面上处理了这一点,因此可以使用:

template <typename U, typename T>
inline U is_lossless(T t)
{
U u = boost::numeric_cast<U>(t);
T t2 = boost::numeric_cast<T>(u); // throw if now out-of-range
if (t != t2)
throw whatever-you-like;
return u;
}

当恢复t2时,对numeric_cast<>的需求是最不明显的:它确保u仍然在范围内,因为从int64_t xdouble y的强制转换值可能成功,但在y中用积分值近似,而不是在int64_t的范围外,因此从double的强制转换具有未定义的行为。

上述内容的合法性/稳健性要求boost::numeric_cast<>正确避免未定义的行为,我尚未验证。