此代码会出现溢出,因为中间结果的类型不依赖于目标类型:
vector< uint8_t > increments;
…
vector< uint32_t > increasing( increments.size() );
partial_sum( increments.begin(), increments.end(), increasing.begin() );
然而,这也是如此(GCC 4.2):
partial_sum( increments.begin(), increments.end(), increasing.begin(),
plus< uint32_t >() );
plus< uint32_t >
不应该提升其操作数并避免溢出?
编辑:我太沉迷于上瘾了。短暂休息后,我坐下来检查实施情况。它这样做:
/* input_iterator::value_type */ __value = __binary_op(__value, *__first);
*++__result = __value;
我不认为这是合规的,所以我会查看最新版本,并可能提交错误...我们转到这里:http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42943
答案 0 :(得分:1)
根据http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#539,自{n3000(最新版)发布以来partial_sum
已完全重新定义:
效果:让VT成为InputIterator 值类型。对于非空的范围, 初始化类型的累加器acc 带*的第一个VT并执行* result = ACC。对于每个迭代器我在[first + 1,最后)按顺序,然后是acc 由acc = acc + * i或acc =修改 binary_op(acc,* i)并分配给 *(结果+(我 - 第一))。
和
然后可以是“扩大”行为 通过编写自定义代理获得 迭代器,有点参与。
我真的看不到以这种方式做事的好处。阅读缺陷报告,我认为除了
之外没有任何理由算法的目的是使用。来执行计算 输入迭代器的类型。
Arrrgh。
编辑:我继续实施了一个扩展的输入迭代器。像宣传的那样工作。
template< class Base, class Wider >
struct widen_iter : iterator< input_iterator_tag, Wider > {
Base b;
widen_iter( Base const &inb = Base() ) : b( inb ) {}
Wider operator*() const { return Wider( *b ); }
Wider const *operator->() const { Wider t( *b ), *ta = &t; return ta; }
widen_iter &operator++() { ++ b; return *this; }
widen_iter operator++(int) { widen_iter t = *this; ++ b; return t; }
bool operator==( widen_iter const &r ) const { return b == r.b; }
bool operator!=( widen_iter const &r ) const { return b != r.b; }
};
template< class Wider, class Base >
widen_iter< Base, Wider >
widener( Base b ) { return widen_iter< Base, Wider >( b ); }
如果有一个通用的逐个仿函数输入迭代器,那么会更短。