我正在做一堆应用数学/信号处理/算法C ++代码。
我已启用-Wconversion
编译器警告,以捕获类型为double
的数字的运行时转换以及int32_t
类型的问题。
显然,在这些转换过程中我总是担心,因为:
int32_t
))每当我担心这种转换时,我通常会使用单行检查:
boost::numeric_cast<DestType>(SourceType)
但是我想在没有boost
的情况下做同样的事情。
直接C ++是否具有等效的boost::numeric_cast<DestType>(SourceType)
?
如果直接C ++没有等效的,那么实施的非boost
是什么?
我认为一个有点类似的检查基本上是一个模板函数,它有一个if语句来检查输入参数是否存在正溢出或负溢出(使用std::numeric_limits<DestType>
::max()
和{{1并抛出异常)。
答案 0 :(得分:1)
https://developers.google.com/identity/sign-in/web/devconsole-project,目前没有标准C ++规范与Boost的boost::numeric_cast<typename Destination>(Source value)
等效。
这是一个只使用标准C ++的直接实现:
template<typename Dst, typename Src>
inline Dst numeric_cast(Src value)
{
const bool positive_overflow_possible = std::numeric_limits<Dst>::max() < std::numeric_limits<Src>::max();
const bool negative_overflow_possible =
std::numeric_limits<Src>::is_signed
or
(std::numeric_limits<Dst>::lowest() > std::numeric_limits<Src>::lowest());
// unsigned <-- unsigned
if((not std::numeric_limits<Dst>::is_signed) and (not std::numeric_limits<Src>::is_signed)) {
if(positive_overflow_possible and (value > std::numeric_limits<Dst>::max())) {
throw std::overflow_error(__PRETTY_FUNCTION__ + std::string(": positive overflow"));
}
}
// unsigned <-- signed
else if((not std::numeric_limits<Dst>::is_signed) and std::numeric_limits<Src>::is_signed) {
if(positive_overflow_possible and (value > std::numeric_limits<Dst>::max())) {
throw std::overflow_error(__PRETTY_FUNCTION__ + std::string(": positive overflow"));
}
else if(negative_overflow_possible and (value < 0)) {
throw std::overflow_error(__PRETTY_FUNCTION__ + std::string(": negative overflow"));
}
}
// signed <-- unsigned
else if(std::numeric_limits<Dst>::is_signed and (not std::numeric_limits<Src>::is_signed)) {
if(positive_overflow_possible and (value > std::numeric_limits<Dst>::max())) {
throw std::overflow_error(__PRETTY_FUNCTION__ + std::string(": positive overflow"));
}
}
// signed <-- signed
else if(std::numeric_limits<Dst>::is_signed and std::numeric_limits<Src>::is_signed) {
if(positive_overflow_possible and (value > std::numeric_limits<Dst>::max())) {
throw std::overflow_error(__PRETTY_FUNCTION__ + std::string(": positive overflow"));
} else if(negative_overflow_possible and (value < std::numeric_limits<Dst>::lowest())) {
throw std::overflow_error(__PRETTY_FUNCTION__ + std::string(": negative overflow"));
}
}
// limits have been checked, therefore safe to cast
return static_cast<Dst>(value);
}
注释:
std::numeric_limits<float>::min()
,而必须使用std::numeric_limits<Dst>::lowest()
,因为::min
返回的是1e-38而不是负浮点值std::numeric_limits
都是const表达式,因此编译器将能够在编译时大大简化这一点(即N if语句将在编译时减少为一个if语句或者没有)