首页 > 解决方案 > MSVC 中从 _Ty 到 int 警告的转换累积

问题描述

我将 MSVC 警告提高到 4 级,并且在使用累积 over boost::circular_buffer 时遇到问题。这段代码:

boost::circular_buffer<unsigned short> shorts;
shorts.resize(10);
unsigned short res = std::accumulate(shorts.begin(), shorts.end(), static_cast<unsigned short>(0));

possible loss of data累积模板中的警告失败(数字):

// FUNCTION TEMPLATE accumulate
template<class _InIt,
    class _Ty,
    class _Fn>
    _NODISCARD inline _Ty accumulate(const _InIt _First, const _InIt _Last, _Ty _Val, _Fn _Reduce_op)
    {   // return noncommutative and nonassociative reduction of _Val and all in [_First, _Last), using _Reduce_op
    _Adl_verify_range(_First, _Last);
    auto _UFirst = _Get_unwrapped(_First);
    const auto _ULast = _Get_unwrapped(_Last);
    for (; _UFirst != _ULast; ++_UFirst)
        {
        _Val = _Reduce_op(_Val, *_UFirst); // <-- THIS IS WHERE THE WARNING IS
        }

    return (_Val);
    }

有什么想法可能是错的吗?

标签: c++visual-c++boost

解决方案


25.9.2 Accumulate [accumulate]定义std::accumulateas的效果acc = std::move(acc) + *i。由于 C++ 出于某种原因不支持小于整数类型的算术运算,而是在求和之前提升 inint两边的参数,因此结果将是. 因此,您在这里会收到一个看似不可避免的警告。+intint

一种可能的解决方法是将累加器定义为unsinged int,然后将最终结果转换为所需的类型:

unsigned short res{static_cast< unsigned short >(::std::accumulate(shorts.begin(), shorts.end(), 0u));

推荐阅读