JTC1/SC22/WG21
N4405
The type of the accumulaters of standard algorithms
std::accumulate and std::inner_product.
Document number: N4405
Project: Programming Language C++, Library Evolution Working Group
Date: 2015-02-11
Reply-To: Vladimir Grigoriev (vlad.moscow@mail.ru)
Preface.
In the description of algorithms std::accumulate and std::inner_product there is said nothing about what type have internally used accumulators of the algorithms. This results in that implementations of the algorithms can have different behaviours.
For example if algorithms std::accumulate is defined like
template <class InputIterator, class T>
T accumulate( InputIterator first, InputIterator last, T init )
{
T acc = init;
for ( ; first != last; ++first ) acc = acc + *first;
return acc;
}
then the following program
#include <iostream>
#include <numeric>
#include <iterator>
int main()
{
int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::cout << std::accumulate<decltype( std::begin( a ) ), const int>
( std::begin( a ), std::end( a ), 0 )
<< std::endl;
return 0;
}
will not compile.
On the other hand if to define the algorithm like
template <class InputIterator, class T>
T accumulate( InputIterator first, InputIterator last, T init )
{
auto acc = init;
for ( ; first != last; ++first ) acc = acc + *first;
return acc;
}
then the above program will compile successfully.
Another example. Sometimes there is a sense to declare
explicitly the template argument that corresponds
to initializer init as reference that to achieve
more effectiveness of the algorithms
by means of avoiding of creating of temporary objects.
However not all implementations of the algorithms can compile for example the following program
#include <iostream>
#include <iterator>
int main()
{
int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
long long acc = 0;
accumulate<decltype( std::begin( a ) ), long long &>
( std::begin( a ), std::end( a ), acc );
std::cout << acc << std::endl;
return 0;
}
Thus the description of the algorithms in the C++ Standard
should explicitly contain words about how the accumulators
of the algorithms are defined that to avoid the ambiguity
in the algorithms' implementations.
Changes to the C++ Standard.
Section 26.7.2 Accumulate.
Change paragraph #1 the following way
1 Effects: Computes its result by defining the accumulator acc like T acc
(T may be a reference type) and initializing it with the initial value
init and then modifies it with acc = acc + *i
or acc = binary_op(acc, *i) for every iterator i
in the range [first,last) in order.289
Section 26.7.3 Inner product
Change paragraph #1 the following way
1 Effects: Computes its result by defining the accumulator
like T acc (T may be a reference type) and initializing it with the initial value
init and then modifying it with acc = acc + (*i1) * (*i2)
or acc = binary_op1(acc, binary_op2(*i1,*i2))
for every iterator i1 in the range [first1,last1)
and iterator i2 in the range [first2,first2
+ (last1 - first1)) in order.