home | help
std::accumulate(3)	       C++ Standard Libary	      std::accumulate(3)

NAME
     std::accumulate - std::accumulate

Synopsis
	Defined in header <numeric>
	template<  class InputIt, class T >			  (1) (constexpr
     since C++20)
	T accumulate( InputIt first, InputIt last, T init );
	template< class InputIt, class T, class BinaryOp >
	T accumulate( InputIt first, InputIt last, T init,	 (2)  (constexpr
     since C++20)
	BinaryOp op );

	Computes the sum of the given value init and the elements in the range
	[first, last).

	1)  Initializes  the  accumulator acc (of type T) with the initial value
     init and then
	modifies it with
	acc = acc + *i
	(until C++20)
	acc = std::move(acc) + *i
	(since C++20) for every iterator i in the range [first, last) in order.
	2) Initializes the accumulator acc (of type T) with  the  initial  value
     init and then
	modifies it with
	acc = op(acc, *i)
	(until C++20)
	acc = op(std::move(acc), *i)
	(since C++20) for every iterator i in the range [first, last) in order.

	If  any  of the following conditions is satisfied, the behavior is unde-
     fined:

	  * T is not CopyConstructible.
	  * T is not CopyAssignable.
	  * op modifies any element of [first, last).
	  * op invalidates any iterator or subrange in [first, last].

Parameters
	first, last - the range of elements to sum
	init	    - initial value of the sum
		      binary operation function object that will be applied.

		      The signature of the function should be equivalent to  the
     following:

		       Ret fun(const Type1 &a, const Type2 &b);
	op	    -
		      The signature does not need to have const &.
		      The  type  Type1 must be such that an object of type T can
     be
		      implicitly converted to  Type1. The type	 Type2	must  be
     such that an
		      object  of  type	InputIt can be dereferenced and then im-
     plicitly
		      converted to  Type2. The type Ret must be such that an ob-
     ject of type
		      T can be assigned a value of type Ret.

Type requirements
	-
	InputIt must meet the requirements of LegacyInputIterator.

Return value
	acc after all modifications.

Possible implementation
				   accumulate (1)
	template<class InputIt, class T>
	constexpr // since C++20
	T accumulate(InputIt first, InputIt last, T init)
	{
	    for (; first != last; ++first)
		init = std::move(init) + *first; // std::move since C++20

	    return init;
	}
				   accumulate (2)
	template<class InputIt, class T, class BinaryOperation>
	constexpr // since C++20
	T accumulate(InputIt first, InputIt last, T init, BinaryOperation op)
	{
	    for (; first != last; ++first)
		init = op(std::move(init), *first); // std::move since C++20

	    return init;
	}

Notes
	std::accumulate performs a left fold. In order to perform a right  fold,
     one must
	reverse  the  order of the arguments to the binary operator, and use re-
     verse
	iterators.

	If left to type inference, op operates on values of  the  same	type  as
     init which can
	result in unwanted casting of the iterator elements. For example,
	std::accumulate(v.begin(),  v.end(),  0) likely does not give the result
     one wishes
	for when v is of type std::vector<double>.

Example
     // Run this code

      #include <functional>
      #include <iostream>
      #include <numeric>
      #include <string>
      #include <vector>

      int main()
      {
	  std::vector<int> v{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

	  int sum = std::accumulate(v.begin(), v.end(), 0);
	  int  product	=  std::accumulate(v.begin(),  v.end(),  1,  std::multi-
     plies<int>());

	  auto dash_fold = [](std::string a, int b)
	  {
	      return std::move(a) + '-' + std::to_string(b);
	  };

	  std::string s = std::accumulate(std::next(v.begin()), v.end(),
					  std::to_string(v[0]),  //  start  with
     first element
					  dash_fold);

	  // Right fold using reverse iterators
	  std::string rs = std::accumulate(std::next(v.rbegin()), v.rend(),
					   std::to_string(v.back()),  //   start
     with last element
					   dash_fold);

	  std::cout << "sum: " << sum << '\n'
		    << "product: " << product << '\n'
		    << "dash-separated string: " << s << '\n'
		    << "dash-separated string (right-folded): " << rs << '\n';
      }

Output:
      sum: 55
      product: 3628800
      dash-separated string: 1-2-3-4-5-6-7-8-9-10
      dash-separated string (right-folded): 10-9-8-7-6-5-4-3-2-1

	Defect reports

	The  following	behavior-changing  defect  reports were applied retroac-
     tively to
	previously published C++ standards.

	   DR	  Applied to	    Behavior  as  published		 Correct
     behavior
	LWG  242   C++98      op could not have side effects	  it cannot mod-
     ify the ranges
								 involved
	LWG 2055  C++20      acc was not moved while being	 it is moved
	(P0616R0)	     accumulated

See also
	adjacent_difference computes the differences between  adjacent	elements
     in a range
			    (function template)
	inner_product	    computes the inner product of two ranges of elements
			    (function template)
	partial_sum	    computes the partial sum of a range of elements
			    (function template)
	reduce		    similar to std::accumulate, except out of order
	(C++17) 	    (function template)
	ranges::fold_left   left-folds a range of elements
	(C++23) 	    (niebloid)

http://cppreference.com 	   2024.06.10		      std::accumulate(3)

home | help