Namespaces
Variants

std::accumulate

cppreference.net에서
 
 
알고리즘 라이브러리
제약된 알고리즘 및 범위에 대한 알고리즘 (C++20)
제약된 알고리즘, 예: ranges::copy, ranges::sort, ...
정렬 및 관련 연산
분할 연산
(C++11)    

정렬 연산
이진 탐색 연산
(분할된 범위에 대해)
집합 연산 (정렬된 범위에 대해)
병합 연산 (정렬된 범위에 대해)
힙 연산
최소/최대 연산
(C++11)
(C++17)
사전식 비교 연산
순열 연산


 
 
헤더 <numeric>
template< class InputIt, class T >
T accumulate( InputIt first, InputIt last, T init );
에 정의됨 (1) (C++20부터 constexpr)
template< class InputIt, class T, class BinaryOp >
T accumulate( InputIt first, InputIt last, T init, BinaryOp op );
(2) (C++20부터 constexpr)

주어진 값 init 과 범위 [first, last) 의 요소들의 합을 계산합니다.

1) 누산기 acc (형식 T)을 초기값 init 으로 초기화한 다음, 범위 acc = acc + *i(C++20까지)acc = std::move(acc) + *i(C++20부터) 내의 모든 반복자 i 에 대해 순서대로 [first, last) 로 수정합니다.
2) 누산기 acc (형식 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 & 가 필요하지는 않습니다.
Type1 타입은 T 타입의 객체가 Type1 으로 암시적으로 변환될 수 있어야 합니다. Type2 타입은 InputIt 타입의 객체가 역참조된 후 Type2 으로 암시적으로 변환될 수 있어야 합니다. Ret 타입은 T 타입의 객체에 Ret 타입의 값을 할당할 수 있어야 합니다. ​

타입 요구사항
-
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 는 왼쪽 폴드(fold) 를 수행합니다. 오른쪽 폴드를 수행하려면 이항 연산자의 인자 순서를 반대로 하고 역방향 반복자를 사용해야 합니다.

타입 추론에 맡길 경우, 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 적용 대상 게시된 동작 올바른 동작
LWG 242 C++98 op 부작용을 가질 수 없었음 관련 범위를 수정할 수 없음

참고 항목

범위 내 인접한 요소들 간의 차이를 계산합니다
(함수 템플릿)
두 범위의 요소들에 대한 내적을 계산합니다
(함수 템플릿)
요소 범위의 부분 합을 계산합니다
(함수 템플릿)
(C++17)
std::accumulate 와 유사하지만 순서가 보장되지 않습니다
(함수 템플릿)
요소 범위를 왼쪽으로 접습니다
(알고리즘 함수 객체)