Namespaces
Variants

std::ranges::borrowed_range, std::ranges::enable_borrowed_range

cppreference.net에서
 
 
Ranges 라이브러리
Range 어댑터
 
헤더에 정의 <ranges>
template< class R >
concept borrowed_range =
    ranges::range<R> &&
    (std::is_lvalue_reference_v<R> ||
     ranges::enable_borrowed_range<std::remove_cvref_t<R>>);
(1) (C++20 이후)
template< class R >
constexpr bool enable_borrowed_range = false;
(2) (C++20 이후)
1) 개념 borrowed_range은 함수가 값을 전달받아 그로부터 얻은 반복자를 댕글링 위험 없이 반환할 수 있는 범위(range)의 요구사항을 정의합니다.
2) 변수 템플릿 enable_borrowed_range은 range가 borrowed_range인지 여부를 나타내는 데 사용됩니다. 기본 템플릿은 false으로 정의됩니다.

의미론적 요구사항

T 가 rvalue reference 타입일 경우 U 를 std:: remove_reference_t < T > 로 정의하고, 그렇지 않으면 T 로 정의한다. U 타입의 변수 u 가 주어졌을 때, T 는 u 로부터 얻은 반복자(iterator)들의 유효성이 해당 변수의 수명에 종속되지 않는 경우에만 borrowed_range 를 모델링한다.

특수화

프로그램은 enable_borrowed_range 를 true 로 특수화하여 프로그램 정의 타입 중 cv-unqualified 타입이 borrowed_range 를 모델링하는 경우에 사용할 수 있으며, false 로 특수화하여 해당하지 않는 타입에 사용할 수 있습니다. 이러한 특수화는 상수 표현식 에서 사용 가능해야 하며 const bool 타입을 가져야 합니다.

표준 라이브러리에서 무조건적으로 빌린 범위

다음 표준 템플릿들의 모든 특수화에 대한 enable_borrowed_range 특수화는 true 로 정의됩니다:

**참고:** 제시된 HTML 코드 내의 모든 텍스트는 이미 C++ 관련 용어이거나 태그 내에 포함되어 있어 번역 대상에서 제외됩니다. 따라서 원본 텍스트를 그대로 유지하였습니다.

표준 라이브러리의 조건부 차용 범위

다음 표준 범위 어댑터들에 대한 enable_borrowed_range 의 특수화는 true 로 정의되며, 이는 std :: ranges :: enable_borrowed_range < V > 가 true 인 경우에만 해당합니다. 여기서 V 는 기반 뷰 타입입니다:

(C++23부터)
(C++23부터)
(C++23부터)
(C++26부터)
  1. ↑ 기본 뷰 V 는 또한 forward_range 를 만족해야 합니다.

다음 표준 범위 어댑터들에 대한 enable_borrowed_range 특수화는 true 로 정의되며, 이는 ( std :: ranges :: enable_borrowed_range < Vs > && ... ) 가 true 인 경우에만 해당합니다. 여기서 Vs... 는 해당 어댑터가 적용하는 모든 뷰 타입들입니다:

(C++23부터)

예제

프로그램 정의 타입에 대한 enable_borrowed_range 특수화를 보여줍니다. 이러한 특수화는 잠재적으로 댕글링(dangling)되는 결과로부터 보호합니다.

#include <algorithm>
#include <array>
#include <cstddef>
#include <iostream>
#include <ranges>
#include <span>
#include <type_traits>
template<typename T, std::size_t N>
struct MyRange : std::array<T, N> {};
template<typename T, std::size_t N>
constexpr bool std::ranges::enable_borrowed_range<MyRange<T, N>> = false;
template<typename T, std::size_t N>
struct MyBorrowedRange : std::span<T, N> {};
template<typename T, std::size_t N>
constexpr bool std::ranges::enable_borrowed_range<MyBorrowedRange<T, N>> = true;
int main()
{
    static_assert(std::ranges::range<MyRange<int, 8>>);
    static_assert(std::ranges::borrowed_range<MyRange<int, 8>> == false);
    static_assert(std::ranges::range<MyBorrowedRange<int, 8>>);
    static_assert(std::ranges::borrowed_range<MyBorrowedRange<int, 8>> == true);
    auto getMyRangeByValue = []{ return MyRange<int, 4>{{1, 2, 42, 3}}; };
    auto dangling_iter = std::ranges::max_element(getMyRangeByValue());
    static_assert(std::is_same_v<std::ranges::dangling, decltype(dangling_iter)>);
    // *dangling_iter; // 컴파일 오류 (즉, 댕글링 보호가 작동합니다.)
    auto my = MyRange<int, 4>{{1, 2, 42, 3}};
    auto valid_iter = std::ranges::max_element(my);
    std::cout << *valid_iter << ' '; // OK: 42
    auto getMyBorrowedRangeByValue = []
    {
        static int sa[4]{1, 2, 42, 3};
        return MyBorrowedRange<int, std::size(sa)>{sa};
    };
    auto valid_iter2 = std::ranges::max_element(getMyBorrowedRangeByValue());
    std::cout << *valid_iter2 << '\n'; // OK: 42
}

출력:

42 42

참고 항목

댕글링(dangling) 상태가 될 것이므로 반환되어서는 안 되는 반복자나 subrange 를 나타내는 플레이스홀더 타입
(클래스)