Namespaces
Variants

std::ranges:: fold_left

From cppreference.net
Algorithm library
Constrained algorithms and algorithms on ranges (C++20)
Constrained algorithms, e.g. ranges::copy , ranges::sort , ...
Execution policies (C++17)
Non-modifying sequence operations
Batch operations
(C++17)
Search operations
Modifying sequence operations
Copy operations
(C++11)
(C++11)
Swap operations
Transformation operations
Generation operations
Removing operations
Order-changing operations
(until C++17) (C++11)
(C++20) (C++20)
Sampling operations
(C++17)

Sorting and related operations
Partitioning operations
Sorting operations
Binary search operations
(on partitioned ranges)
Set operations (on sorted ranges)
Merge operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Lexicographical comparison operations
Permutation operations
C library
Numeric operations
Operations on uninitialized memory
Constrained algorithms
All names in this menu belong to namespace std::ranges
Non-modifying sequence operations
Modifying sequence operations
Partitioning operations
Sorting operations
Binary search operations (on sorted ranges)
Set operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Permutation operations
Fold operations
Operations on uninitialized storage
Return types
헤더 파일에 정의됨 <algorithm>
호출 서명
(1)
template < std:: input_iterator I, std:: sentinel_for < I > S, class T,

/* indirectly-binary-left-foldable */ < T, I > F >

constexpr auto fold_left ( I first, S last, T init, F f ) ;
(C++23부터)
(C++26까지)
template < std:: input_iterator I, std:: sentinel_for < I > S,

class T = std:: iter_value_t < I > ,
/* indirectly-binary-left-foldable */ < T, I > F >

constexpr auto fold_left ( I first, S last, T init, F f ) ;
(C++26부터)
(2)
template < ranges:: input_range R, class T,

/* indirectly-binary-left-foldable */
< T, ranges:: iterator_t < R >> F >

constexpr auto fold_left ( R && r, T init, F f ) ;
(C++23부터)
(C++26까지)
template < ranges:: input_range R, class T = ranges:: range_value_t < R > ,

/* indirectly-binary-left-foldable */
< T, ranges:: iterator_t < R >> F >

constexpr auto fold_left ( R && r, T init, F f ) ;
(C++26부터)
헬퍼 개념
template < class F, class T, class I >
concept /* indirectly-binary-left-foldable */ = /* 설명 참조 */ ;
(3) ( 설명 전용* )

주어진 범위의 요소들을 좌측- 폴드 합니다. 즉, 다음과 같은 체인 표현식의 평가 결과를 반환합니다:
f(f(f(f(init, x 1 ), x 2 ), ...), x n ) , 여기서 x 1 , x 2 , ..., x n 은 범위의 요소들입니다.

비공식적으로, ranges::fold_left 는 이항 predicate를 받는 std::accumulate 의 overload처럼 동작합니다.

[ first , last ) 가 유효한 범위가 아닌 경우, 동작은 정의되지 않습니다.

1) 범위는 [ first , last ) 입니다. 다음 코드와 동일합니다: return ranges:: fold_left_with_iter ( std :: move ( first ) , last, std :: move ( init ) , f ) . value .
2) (1) 와 동일하지만, r 을 범위로 사용하며, 마치 ranges:: begin ( r ) first 로, ranges:: end ( r ) last 로 사용하는 것과 같습니다.
3) 다음과 동등함:
도우미 개념들
template < class F, class T, class I, class U >

concept /*indirectly-binary-left-foldable-impl*/ =
std:: movable < T > &&
std:: movable < U > &&
std:: convertible_to < T, U > &&
std:: invocable < F & , U, std:: iter_reference_t < I >> &&
std:: assignable_from < U & ,

std:: invoke_result_t < F & , U, std:: iter_reference_t < I >>> ;
(3A) ( 설명 전용* )
template < class F, class T, class I >

concept /*indirectly-binary-left-foldable*/ =
std:: copy_constructible < F > &&
std:: indirectly_readable < I > &&
std:: invocable < F & , T, std:: iter_reference_t < I >> &&
std:: convertible_to < std:: invoke_result_t < F & , T, std:: iter_reference_t < I >> ,
std:: decay_t < std:: invoke_result_t < F & , T, std:: iter_reference_t < I >>>> &&
/*indirectly-binary-left-foldable-impl*/ < F, T, I,

std:: decay_t < std:: invoke_result_t < F & , T, std:: iter_reference_t < I >>>> ;
(3B) ( 설명 전용* )

이 페이지에서 설명하는 함수형 개체들은 algorithm function objects (일반적으로 niebloids 로 알려진)입니다. 즉:

목차

매개변수

first, last - 폴드할 요소들의 범위 를 정의하는 반복자-센티넬 쌍
r - 폴드할 요소들의 범위
init - 폴드의 초기값
f - 이항 함수 객체

반환값

주어진 범위에 대해 f 를 사용한 왼쪽- 폴드 의 결과를 포함하는 U 타입의 객체. 여기서 U std:: decay_t < std:: invoke_result_t < F & , T, std:: iter_reference_t < I >>> 와 동등합니다.

범위가 비어 있으면, U ( std :: move ( init ) ) 가 반환됩니다.

가능한 구현

struct fold_left_fn
{
    template<std::input_iterator I, std::sentinel_for<I> S, class T = std::iter_value_t<I>,
             /* 간접적으로-이항-좌측-접기-가능 */<T, I> F>
    constexpr auto operator()(I first, S last, T init, F f) const
    {
        using U = std::decay_t<std::invoke_result_t<F&, T, std::iter_reference_t<I>>>;
        if (first == last)
            return U(std::move(init));
        U accum = std::invoke(f, std::move(init), *first);
        for (++first; first != last; ++first)
            accum = std::invoke(f, std::move(accum), *first);
        return std::move(accum);
    }
    template<ranges::input_range R, class T = ranges::range_value_t<R>,
             /* 간접적으로-이항-좌측-접기-가능 */<T, ranges::iterator_t<R>> F>
    constexpr auto operator()(R&& r, T init, F f) const
    {
        return (*this)(ranges::begin(r), ranges::end(r), std::move(init), std::ref(f));
    }
};
inline constexpr fold_left_fn fold_left;

복잡도

정확히 ranges:: distance ( first, last ) 번 함수 객체 f 가 적용됩니다.

참고 사항

다음 표는 모든 제약 조건을 가진 폴딩 알고리즘들을 비교한 것입니다:

폴드 함수 템플릿 시작 방향 초기값 반환 타입
ranges :: fold_left 왼쪽 init U
ranges:: fold_left_first 왼쪽 첫 번째 요소 std:: optional < U >
ranges:: fold_right 오른쪽 init U
ranges:: fold_right_last 오른쪽 마지막 요소 std:: optional < U >
ranges:: fold_left_with_iter 왼쪽 init

(1) ranges:: in_value_result < I, U >

(2) ranges:: in_value_result < BR, U > ,

여기서 BR ranges:: borrowed_iterator_t < R >

ranges:: fold_left_first_with_iter 왼쪽 첫 번째 요소

(1) ranges:: in_value_result < I, std:: optional < U >>

(2) ranges:: in_value_result < BR, std:: optional < U >>

여기서 BR ranges:: borrowed_iterator_t < R >

기능 테스트 매크로 표준 기능
__cpp_lib_ranges_fold 202207L (C++23) std::ranges 폴드 알고리즘
__cpp_lib_algorithm_default_value_type 202403L (C++26) 목록 초기화 for algorithms ( 1,2 )

예제

#include <algorithm>
#include <complex>
#include <functional>
#include <iostream>
#include <ranges>
#include <string>
#include <utility>
#include <vector>
int main()
{
    namespace ranges = std::ranges;
    std::vector v{1, 2, 3, 4, 5, 6, 7, 8};
    int sum = ranges::fold_left(v.begin(), v.end(), 0, std::plus<int>()); // (1)
    std::cout << "sum: " << sum << '\n';
    int mul = ranges::fold_left(v, 1, std::multiplies<int>()); // (2)
    std::cout << "mul: " << mul << '\n';
    // 벡터 내 모든 pair의 std::pair::second 값의 곱을 구함:
    std::vector<std::pair<char, float>> data {{'A', 2.f}, {'B', 3.f}, {'C', 3.5f}};
    float sec = ranges::fold_left
    (
        data | ranges::views::values, 2.0f, std::multiplies<>()
    );
    std::cout << "sec: " << sec << '\n';
    // 프로그램 정의 함수 객체(람다 표현식) 사용:
    std::string str = ranges::fold_left
    (
        v, "A", [](std::string s, int x) { return s + ':' + std::to_string(x); }
    );
    std::cout << "str: " << str << '\n';
    using CD = std::complex<double>;
    std::vector<CD> nums{{1, 1}, {2, 0}, {3, 0}};
    #ifdef __cpp_lib_algorithm_default_value_type
        auto res = ranges::fold_left(nums, {7, 0}, std::multiplies{}); // (2)
    #else
        auto res = ranges::fold_left(nums, CD{7, 0}, std::multiplies{}); // (2)
    #endif
    std::cout << "res: " << res << '\n';
}

출력:

sum: 36
mul: 40320
sec: 42
str: A:1:2:3:4:5:6:7:8
res: (42,42)

참고문헌

  • C++23 표준 (ISO/IEC 14882:2024):
  • 27.6.18 Fold [alg.fold]

참고 항목

첫 번째 요소를 초기값으로 사용하여 요소 범위를 왼쪽으로 접음
(알고리즘 함수 객체)
요소 범위를 오른쪽으로 접음
(알고리즘 함수 객체)
마지막 요소를 초기값으로 사용하여 요소 범위를 오른쪽으로 접음
(알고리즘 함수 객체)
요소 범위를 왼쪽으로 접고 pair (반복자, 값)을 반환함
(알고리즘 함수 객체)
첫 번째 요소를 초기값으로 사용하여 요소 범위를 왼쪽으로 접고 pair (반복자, optional )을 반환함
(알고리즘 함수 객체)
요소 범위를 합산하거나 접음
(함수 템플릿)
(C++17)
std::accumulate 와 유사하지만 순서가 보장되지 않음
(함수 템플릿)