C++ Boost或标准库是否提供了检查强制转换是否无损的方法?

C++ Boost或标准库是否提供了检查强制转换是否无损的方法?,c++,boost,C++,Boost,我正在寻找一个标准库或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&

我正在寻找一个标准库或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中有什么功能,但它是一个很大的库。任何使用强制转换的实现都必须根据4.9[conv.fpint]小心超出范围的值的未定义行为,但由于
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;
}
模板
内联U是无损的(T)
{
U=boost::数值型(t);
t2=boost::numeric_cast(u);//现在超出范围时抛出
如果(t!=t2)
随你便;
返回u;
}
恢复
t2
时需要
numeric\u cast
最不明显:它确保
u
仍在范围内,因为从
int64_t x
double y
的值转换可能会成功,但在
y
中用一个整数近似,而不是
int64_t
的范围之外,因此从
double
进行的回退具有未定义的行为


上述内容的合法性/稳健性要求
boost::numeric\u cast
正确避免未定义的行为,我尚未验证这些行为。

编写一个执行cast的函数,然后比较前后是否相等。如果您希望得到一个没有cast往返的解决方案,这可能是一个比你意识到的更难的问题。例如,
float
不能表示16777217。@IgorTandetnik:这不是一个好主意-在某些情况下,它会给出未定义的行为(例如问题中的
lossless_cast(1E200);
case)。有趣的是,double也不能表示
1.2
lossless…)谁能结束这个问题,请把我的问题再读一遍。这不是一个重复的问题。我很确定
boost::numeric\u cast
的目的是避免UB案例。目前的实施是否真的成功还很难说;请参阅@Nemo:您希望这是他们的意图,尽管可能很难快速完成(在CPU周期的意义上),而且他们可能已经发现boost Targeted的特定CPU上未定义的行为符合其可移植性要求,而不是在所有可能的目标上进行标准授权的可移植性。我刚刚在我的电脑上调出了代码,将查看您的链接-干杯。由于可以从参数推断出
T
的类型,因此将
typename U
作为第一个模板参数是否有价值?我认为,这将允许一种类似于boost和核心语言所提供的“强制转换”语法。@DrewDormann:当然,这让我自己陷入了困境。干杯
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;
}