首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >c++有一个等价的boost::numeric_cast<DestType>(SourceType)吗?

c++有一个等价的boost::numeric_cast<DestType>(SourceType)吗?
EN

Stack Overflow用户
提问于 2018-04-04 18:40:28
回答 1查看 2.2K关注 0票数 8

我正在做一堆applied-mathematics/signal-processing/algorithms C++代码。

我已经启用了-Wconversion编译器警告,以捕捉double类型为int32_t类型的数字的运行时转换等问题。

很明显,在这些转变过程中,我一直很关注,因为:

  • 数字损失十进制值
  • 可能的正溢出或负溢出(“正溢出”是指double的值大于INT32_MAX,并试图将该值存储在目标类型中(本例中为int32_t))。

每当我考虑到这样的转换时,我通常使用一行检查:

代码语言:javascript
复制
boost::numeric_cast<DestType>(SourceType)

但是,我想在没有boost的情况下做同样的事情。

C++有一个等价的C++

如果直implementation?没有等价的C++,那么什么是可比较的非**boost**C++?

我认为在某种程度上类似的检查基本上是一个模板函数,它有一个if语句来检查输入参数是否有正溢出或负溢出(通过使用std::numeric_limits<DestType> ::max()::min()并抛出一个异常)。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-04-04 19:27:15

As @SergeyA stated,不,标准的C++规范目前没有与Boost的规范相当的

下面是一个只使用标准C++的直接实现:

代码语言:javascript
复制
template<typename Dst, typename Src>
inline Dst numeric_cast(Src value)
{
    typedef std::numeric_limits<Dst> DstLim;
    typedef std::numeric_limits<Src> SrcLim;

    const bool positive_overflow_possible = DstLim::max() < SrcLim::max();
    const bool negative_overflow_possible =
            SrcLim::is_signed
            or
            (DstLim::lowest() > SrcLim::lowest());

    // unsigned <-- unsigned
    if((not DstLim::is_signed) and (not SrcLim::is_signed)) {
        if(positive_overflow_possible and (value > DstLim::max())) {
            throw std::overflow_error(__PRETTY_FUNCTION__ +
                                      std::string(": positive overflow"));
        }
    }
    // unsigned <-- signed
    else if((not DstLim::is_signed) and SrcLim::is_signed) {
        if(positive_overflow_possible and (value > DstLim::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(DstLim::is_signed and (not SrcLim::is_signed)) {
        if(positive_overflow_possible and (value > DstLim::max())) {
            throw std::overflow_error(__PRETTY_FUNCTION__ +
                                      std::string(": positive overflow"));
        }
    }
    // signed <-- signed
    else if(DstLim::is_signed and SrcLim::is_signed) {
        if(positive_overflow_possible and (value > DstLim::max())) {
            throw std::overflow_error(__PRETTY_FUNCTION__ +
                                      std::string(": positive overflow"));
        } else if(negative_overflow_possible and (value < DstLim::lowest())) {
            throw std::overflow_error(__PRETTY_FUNCTION__ +
                                      std::string(": negative overflow"));
        }
    }

    // limits have been checked, therefore safe to cast
    return static_cast<Dst>(value);
} 

注:

  • 编译器是g++版本4.8.5。
  • 编译器标志:
    • -std=c++0x
    • -O0
    • -g3
    • -pedantic
    • -学究-错误
    • -Wall
    • -Wextra
    • -Werror
    • -Wconversion
    • -c
    • -fmessage-长度=0
    • -瓦什-转换
    • -fPIC
    • -MMD
    • -MP

  • 对于浮点类型,您不能使用std::numeric_limits<float>::min(),而是必须使用std::numeric_limits<Dst>::lowest(),因为::min返回值为1e-38,而不是负浮点值。
  • 许多std::numeric_limits是const表达式,所以编译器可以在编译时大大简化这一点(也就是说,N个if语句将在编译时减少到一个if-语句,或者没有)。
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49658182

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档