Namespaces
Variants

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

From cppreference.net
Ranges library
Range adaptors
헤더 파일에 정의됨 <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 개념은 함수가 값을 기준으로 취할 수 있고, 댕글링의 위험 없이 해당 범위에서 얻은 반복자를 반환할 수 있는 범위의 요구 사항을 정의합니다.
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 를 나타내는 플레이스홀더 타입
(클래스)