std:: accumulate
|
Определено в заголовке
<numeric>
|
||
|
template
<
class
InputIt,
class
T
>
T accumulate ( InputIt first, InputIt last, T init ) ; |
(1) | (constexpr начиная с C++20) |
|
template
<
class
InputIt,
class
T,
class
BinaryOp
>
T accumulate ( InputIt first, InputIt last, T init, BinaryOp op ) ; |
(2) | (constexpr начиная с C++20) |
Вычисляет сумму заданного значения
init
и элементов в диапазоне
[
first
,
last
)
.
T
) начальным значением
init
и затем модифицирует его с помощью
acc
=
acc
+
*
i
(до C++20)
acc
=
std
::
move
(
acc
)
+
*
i
(начиная с C++20)
для каждого итератора
i
в диапазоне
[
first
,
last
)
в порядке следования.
T
) начальным значением
init
и затем модифицирует его с помощью
acc
=
op
(
acc,
*
i
)
(до C++20)
acc
=
op
(
std
::
move
(
acc
)
,
*
i
)
(начиная с C++20)
для каждого итератора
i
в диапазоне
[
first
,
last
)
в порядке следования.
Если выполняется любое из следующих условий, поведение не определено:
-
Tне является CopyConstructible . -
Tне является CopyAssignable . -
op
изменяет любой элемент в
[first,last). -
op
делает недействительным любой итератор или поддиапазон в
[first,last].
Содержание |
Параметры
| first, last | - | пара итераторов, определяющих диапазон элементов для аккумуляции |
| init | - | начальное значение аккумуляции |
| op | - |
функциональный объект бинарной операции, который будет применён.
Сигнатура функции должна быть эквивалентна следующей: Ret fun ( const Type1 & a, const Type2 & b ) ;
Сигнатура не обязана содержать
const
&
.
|
| Требования к типам | ||
-
InputIt
должен удовлетворять требованиям
LegacyInputIterator
.
|
||
Возвращаемое значение
acc после всех модификаций.
Возможная реализация
| 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; } |
Примечания
std::accumulate
выполняет левую
свертку
. Для выполнения правой свертки необходимо изменить порядок аргументов бинарного оператора и использовать обратные итераторы.
Если оставить вывод типов, op работает со значениями того же типа, что и init , что может привести к нежелательному приведению типов элементов итератора. Например, std :: accumulate ( v. begin ( ) , v. end ( ) , 0 ) вероятно не даст желаемого результата, когда v имеет тип std:: vector < double > .
Пример
#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::multiplies<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]), // начинаем с первого элемента dash_fold); // Правое свертывание с использованием обратных итераторов std::string rs = std::accumulate(std::next(v.rbegin()), v.rend(), std::to_string(v.back()), // начинаем с последнего элемента dash_fold); std::cout << "sum: " << sum << '\n' << "product: " << product << '\n' << "dash-separated string: " << s << '\n' << "dash-separated string (right-folded): " << rs << '\n'; }
Вывод:
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
Отчёты о дефектах
Следующие отчеты об изменениях в поведении, содержащие описания дефектов, были применены ретроактивно к ранее опубликованным стандартам C++.
| DR | Applied to | Behavior as published | Correct behavior |
|---|---|---|---|
| LWG 242 | C++98 | op не мог иметь побочных эффектов | он не может изменять задействованные диапазоны |
Смотрите также
|
вычисляет разности между соседними элементами в диапазоне
(шаблон функции) |
|
|
вычисляет скалярное произведение двух диапазонов элементов
(шаблон функции) |
|
|
вычисляет частичную сумму диапазона элементов
(шаблон функции) |
|
|
(C++17)
|
аналогично
std::accumulate
, но без сохранения порядка
(шаблон функции) |
|
(C++23)
|
выполняет левую свертку диапазона элементов
(функциональный объект алгоритма) |