标准库/升级中是否有一个函数可以检查强制转换是否会导致目标类型的溢出/下溢?例如:
unsigned value = static_cast<unsigned>(12.3); // this should pass (lossy but no overflow)
unsigned value = static_cast<unsigned>(1E123); // this should fail
unsigned value = static_cast<unsigned>(-2); // this should also fail
这样的某些东西存在吗?对于上面的示例,该功能可能具有与此类似的功能:
template <typename Source, typename Target>
bool checkNoOverflow(const Source value)
{
return value >= std::numeric_limits<Target>::lowest() && value <= std::numeric_limits<Target>::max();
}
以上只是一个简化的例子,在这样的角落情况下会失败:
unsigned value = static_cast<unsigned>(-0.1); // valid, result is 0
要明确的是,我并没有询问如何编写适用于所有情况的函数,而是在标准库中的现有功能之后或者为我这样做的提升。< / p>
答案 0 :(得分:4)
不幸的是,C ++标准库中不存在这样的函数。
如果您有权访问Boost,那么boost::numeric_cast
应该完全符合您的要求。它将执行两种数字类型之间的转换,除非转换超出目标类型的范围。在这种情况下,会抛出boost::numeric::bad_numeric_cast
异常。
如果您对实现自己的转换感到好奇,可以查看Bjarne Stroustrup(ISBN 978-0321563842)的 C ++编程语言第4版。
在第11.5章中,他定义了一个narrow_cast
:
template<class Target, class Source>
Target narrow_cast(Source v)
{
auto r = static_cast<Target>(v); // convert the value to the target type
if (static_cast<Source>(r)!=v)
throw runtime_error("narrow_cast<>() failed");
return r;
}
这个实现非常简单,并没有像Boost那样完善,但可以想象地进行修改以满足您的需求。