Namespaces
Variants

std::ranges::fold_left_first

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

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


 
제약된 알고리즘
이 메뉴의 모든 이름은 네임스페이스 std::ranges
비수정 시퀀스 연산
수정 시퀀스 연산
분할 연산
정렬 연산
이진 탐색 연산 (정렬된 범위에 대해)
       
       
집합 연산 (정렬된 범위에 대해)
힙 연산
최소/최대 연산
       
       
순열 연산
폴드 연산
수치 연산
(C++23)            
초기화되지 않은 저장소에 대한 연산
반환 타입
 
헤더에 정의됨 <algorithm>
호출 시그니처
template< std::input_iterator I, std::sentinel_for<I> S,
          /*indirectly-binary-left-foldable*/<std::iter_value_t<I>, I> F >
requires std::constructible_from<std::iter_value_t<I>, std::iter_reference_t<I>>
constexpr auto
    fold_left_first( I first, S last, F f );
(1) (C++23부터)
template< ranges::input_range R,
          /*indirectly-binary-left-foldable*/<
                ranges::range_value_t<R>, ranges::iterator_t<R>> F >
requires std::constructible_from<
             ranges::range_value_t<R>, ranges::range_reference_t<R>>
constexpr auto
    fold_left_first( R&& r, F f );
(2) (C++23부터)
헬퍼 개념
template< class F, class T, class I >
concept /*indirectly-binary-left-foldable*/ = /* see description */;
(3) (설명 전용*)

주어진 범위의 요소를 왼쪽-폴드합니다. 즉, 체인 표현식:
f(f(f(f(x1, x2), x3), ...), xn)의 평가 결과를 반환합니다. 여기서 x1, x2, ..., xn는 범위의 요소입니다.

비공식적으로, ranges::fold_left_first는 이진 술어를 받는 std::accumulate의 오버로드처럼 동작하지만, 초기 요소로 *first를 내부적으로 사용합니다.

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

1) 범위는 [first, last)입니다. 다음과 동일: return ranges::fold_left_first_with_iter(std::move(first), last, 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) (설명 전용*)

이 페이지에 설명된 함수 유사 개체는 알고리즘 함수 객체입니다 (비공식적으로 니블로이드로 알려짐). 즉:

매개변수

first, last - 접기할 요소들의 범위 를 정의하는 반복자-감시자 쌍
r - 접기할 요소들의 범위
f - 이항 함수 객체

반환값

주어진 범위에 대한 왼쪽- 폴드 의 결과를 포함하는 std:: optional < U > 타입의 객체를 반환합니다. 여기서 U 는 decltype ( ranges:: fold_left ( std :: move ( first ) , last, std:: iter_value_t < I > ( * first ) , f ) ) 와 동등합니다.

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

가능한 구현

struct fold_left_first_fn
{
    template<std::input_iterator I, std::sentinel_for<I> S,
             /*indirectly-binary-left-foldable*/<std::iter_value_t<I>, I> F>
    requires
        std::constructible_from<std::iter_value_t<I>, std::iter_reference_t<I>>
    constexpr auto operator()(I first, S last, F f) const
    {
        using U = decltype(
            ranges::fold_left(std::move(first), last, std::iter_value_t<I>(*first), f)
        );
        if (first == last)
            return std::optional<U>();
        std::optional<U> init(std::in_place, *first);
        for (++first; first != last; ++first)
            *init = std::invoke(f, std::move(*init), *first);
        return std::move(init);
    }
    template<ranges::input_range R,
             /*indirectly-binary-left-foldable*/<
                 ranges::range_value_t<R>, ranges::iterator_t<R>> F>
    requires
        std::constructible_from<ranges::range_value_t<R>, ranges::range_reference_t<R>>
    constexpr auto operator()(R&& r, F f) const
    {
        return (*this)(ranges::begin(r), ranges::end(r), std::ref(f));
    }
};
inline constexpr fold_left_first_fn fold_left_first;

복잡도

정확히 ranges:: distance ( first, last ) - 1 (범위가 비어 있지 않다고 가정할 때)번 함수 객체 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 폴드 알고리즘

예제

#include <algorithm>
#include <array>
#include <functional>
#include <ranges>
#include <utility>
int main()
{
    constexpr std::array v{1, 2, 3, 4, 5, 6, 7, 8};
    static_assert
    (
        *std::ranges::fold_left_first(v.begin(), v.end(), std::plus{}) == 36
        && *std::ranges::fold_left_first(v, std::multiplies{}) == 40320
    );
    constexpr std::array w
    {
        1, 2, 3, 4, 13,
        1, 2, 3, 4, 13,
        1, 2, 3, 4, 13,
        1, 2, 3, 4,
    };
    static_assert
    (
        "전제 조건에 의해 홀수 번 나타나는 유일한 값을 찾으세요:"
        && *std::ranges::fold_left_first(w, [](int p, int q){ return p ^ q; }) == 13
    );
    constexpr auto pairs = std::to_array<std::pair<char, float>>
    ({
        {'A', 3.0f},
        {'B', 3.5f},
        {'C', 4.0f}
    });
    static_assert
    (
        "pairs에서 모든 pair::second의 곱을 구하세요:"
        && *std::ranges::fold_left_first
        (
            pairs | std::ranges::views::values, std::multiplies{}
        ) == 42
    );
}

참조문헌

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

참고 항목

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