Namespaces
Variants

std::ranges::fold_right_last

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

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


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

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

비공식적으로 ranges::fold_right_last는 ranges::fold_left(views::reverse(r), *--last, /*flipped*/(f))처럼 동작합니다 (범위가 비어 있지 않다고 가정).

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

1) 범위는 [first, last)입니다. U를 decltype(ranges::fold_right(first, last, std::iter_value_t<I>(*first), f))으로 지정하면, 다음 표현식과 동등합니다:
if (first == last)
    return std::optional<U>();
I tail = ranges::prev(ranges::next(first, std::move(last)));
return std::optional<U>(std::in_place, ranges::fold_right(std::move(first), tail,
    std::iter_value_t<I>(*tail), std::move(f)));
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) (설명 전용*)
4) 동등합니다:
헬퍼 컨셉
template< class F, class T, class I >
concept /*indirectly-binary-right-foldable*/ =
    /*indirectly-binary-left-foldable*/</*flipped*/<F>, T, I>;
(4A) (설명 전용*)
헬퍼 클래스 템플릿
template< class F >
class /*flipped*/
{
    F f;    // exposition only
public:
    template< class T, class U >
        requires std::invocable<F&, U, T>
    std::invoke_result_t<F&, U, T> operator()( T&&, U&& );
};
(4B) (설명 전용*)

이 페이지에 설명된 함수형 엔티티는 알고리즘 함수 객체입니다 (비공식적으로 niebloids라고 함). 즉:

  • 이들 중 하나를 호출할 때 명시적 템플릿 인자 목록을 지정할 수 없습니다.
  • 이들 중 어느 것도 인자 종속 조회에 보이지 않습니다.
  • 이들 중 하나가 일반 비한정 조회에 의해 함수 호출 연산자 왼쪽의 이름으로 발견되면, 인자 종속 조회가 억제됩니다.

매개변수

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

반환값

주어진 범위에 대한 오른쪽 폴드 의 결과를 포함하는 std:: optional < U > 타입의 객체.

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

가능한 구현

struct fold_right_last_fn
{
    template<std::bidirectional_iterator I, std::sentinel_for<I> S,
             /*indirectly-binary-right-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_right(first, last, std::iter_value_t<I>(*first), f));
        if (first == last)
            return std::optional<U>();
        I tail = ranges::prev(ranges::next(first, std::move(last)));
        return std::optional<U>(std::in_place,
            ranges::fold_right(std::move(first), tail, std::iter_value_t<I>(*tail),
                               std::move(f)));
    }
    template<ranges::bidirectional_range R,
             /*indirectly_binary_right_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_right_last_fn fold_right_last;

복잡도

정확히 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 폴드 알고리즘

예제

#include <algorithm>
#include <functional>
#include <iostream>
#include <ranges>
#include <utility>
#include <vector>
int main()
{
    auto v = {1, 2, 3, 4, 5, 6, 7, 8};
    std::vector<std::string> vs {"A", "B", "C", "D"};
    auto r1 = std::ranges::fold_right_last(v.begin(), v.end(), std::plus<>()); // (1)
    std::cout << "*r1: " << *r1 << '\n';
    auto r2 = std::ranges::fold_right_last(vs, std::plus<>()); // (2)
    std::cout << "*r2: " << *r2 << '\n';
    // 프로그램 정의 함수 객체 사용 (람다 표현식):
    auto r3 = std::ranges::fold_right_last(v, [](int x, int y) { return x + y + 99; });
    std::cout << "*r3: " << *r3 << '\n';
    // 벡터 내 모든 pair의 second 값의 곱 구하기:
    std::vector<std::pair<char, float>> data {{'A', 3.f}, {'B', 3.5f}, {'C', 4.f}};
    auto r4 = std::ranges::fold_right_last
    (
        data | std::ranges::views::values, std::multiplies<>()
    );
    std::cout << "*r4: " << *r4 << '\n';
}

출력:

*r1: 36
*r2: ABCD
*r3: 729
*r4: 42

참고문헌

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

참고 항목

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