std::ranges::view, std::ranges::enable_view, std::ranges::

From cppreference.com
< cpp‎ | ranges
Ranges library
Range adaptors
Defined in header <ranges>
template < class T>
concept view = ranges::range <T> && std::movable <T> && ranges:: enable_view <T> ;
(1) (since C++20)
template < class T>

constexpr bool enable_view =

std::derived_from <T, view_base> || /*is-derived-from-view-interface*/ <T> ;
(2) (since C++20)
struct view_base { };
(3) (since C++20)
1) The view concept specifies the requirements of a range
2) The enable_view variable template is used to indicate whether a range is a view. /*is-derived-from-view-interface*/<T> is true if and only if T has exactly one public base class ranges::view_interface<U> for some type U, and T has no base classes of type ranges::view_interface<V> for any other type V.
Users may specialize enable_view to true for cv-unqualified program-defined types which model view, and false for types which do not. Such specializations must be usable in constant expressions and have type const bool
3) Deriving from view_base enables range types to model view.

Semantic requirements

1) T models view only if:
  • move construction of T has constant time complexity, and
  • if N copies and/or moves are made from a T object holding M elements, then these N objects have 𝓞(N+M) destruction (which implies that a moved-from view object has 𝓞(1)
  • either std::copy_constructible<T> is false, or copy construction of T
  • either std::copyable<T> is false, or copy assignment of T

Specializations

Specializations of enable_view for all specializations of the following standard templates are defined as true:

(since C++26)

Notes

Examples of view types are:

A copyable container such as std::vector < std::string > generally does not meet the semantic requirements of view

While views were originally described as cheaply copyable and non-owning ranges, a type is not required to be copyable or non-owning for it to model view. However, it must still be cheap to copy (if it is copyable), move, assign, and destroy, so that range adaptors

By default, a type modeling movable and range is considered a view if it is publicly and unambiguously derived from view_base, or exactly one specialization of std::ranges::view_interface

Example

A minimum view.

#include <ranges>
 
struct ArchetypalView : std::ranges::view_interface<ArchetypalView>
{
    int* begin();
    int* end();
};
 
static_assert(std::ranges::view<ArchetypalView>);

Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR Applied to Behavior as published Correct behavior
P2325R3 C++20 view required default_initializable does not require
LWG 3549 C++20 enable_view did not detect inheritance from view_interface detects
P2415R2 C++20 the restriction on the time complexity of destruction was too strict relaxed