【发布时间】:2010-02-03 02:36:43
【问题描述】:
此代码存在溢出问题,因为中间结果的类型不依赖于目标类型:
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
【问题讨论】:
-
我认为你是对的 - 问题不在于
plus是否转换其参数(它当然会),问题在于 26.4.3/1 表示分配给第二个输出是binary_op(*first, *(first+1)),而不是InputIterator::value_type(binary_op(*first, *(first+1))。但是应该如何实施呢?如果 BinaryOperation 有一个result_type,那么它可能会使用它,但函数没有 result_type,当然你可以将函数指针传递给 partial_sum?也许对我来说太晚了...... -
啊,函数指针。我找不到操作对象的任何具体要求,除了 §25/8 (sorta),它只是可以用两个参数调用。模板可以从函数中提取返回类型,尽管这会使更改产生更大的影响。
-
与其从BinaryFunction推导出类型,不如用OutputIterator的value_type代替InputIterator的类型?
-
@visitor:我假设是因为例如 OutputIterator 可能具有非常狭窄的值类型,在这种情况下,您也不希望在实际分配之前丢弃信息。当 BinaryFunction 是模加法时没有区别,因为提前进行转换不会改变结果,但对于其他函数会。但更糟糕的是,OutputIterator 的值类型甚至可能无法转换为 binary_op 的参数类型。标准并没有说它必须是,所以实现不能假设它。
-
我的意思是,为了避免溢出,您宁愿从较小的类型转到较大的类型,而不是尝试将结果存储在更小的类型中。最终,如果类型不同,则要么存在转换,要么您以某种方式得到编译器错误。还有为什么不能给它一个可以接受输出类型的binary_op呢?