std::ranges::view, std::ranges::enable_view, std::ranges::view_base - cppreference.com (original) (raw)
| Defined in header | ||
|---|---|---|
| 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) |
| struct view_base { }; | (3) | (since C++20) |
The
viewconcept specifies the requirements of a range type that has suitable semantic properties for use in constructing range adaptor pipelines.The
enable_viewvariable template is used to indicate whether a range is aview. /*is-derived-from-view-interface*/<T> is true if and only ifThas exactly one public base class ranges::view_interface<U> for some typeU, andThas no base classes of type ranges::view_interface<V> for any other typeV.
Users may specializeenable_viewto true for cv-unqualified program-defined types which modelview, and false for types which do not. Such specializations must be usable in constant expressions and have type const bool.Deriving from
view_baseenables range types to modelview.
[edit] Semantic requirements
Tmodelsviewonly if:
- move construction of
Thas constant time complexity, and - if \(\scriptsize N\)N copies and/or moves are made from a
Tobject holding \(\scriptsize M\)M elements, then these \(\scriptsize N\)N objects have \(\scriptsize \mathcal{O}{(N+M)}\)𝓞(N+M) destruction (which implies that a moved-fromviewobject has \(\scriptsize \mathcal{O}{(1)}\)𝓞(1) destruction), and - either std::copy_constructible<T> is false, or copy construction of
Thas constant time complexity, and - either std::copyable<T> is false, or copy assignment of
Thas no more time complexity than destruction followed by copy construction.
[edit] Specializations
Specializations of enable_view for all specializations of the following standard templates are defined as true:
[edit] Notes
Examples of view types are:
- A range type that wraps a pair of iterators, e.g., std::ranges::subrange<I>.
- A range type that holds its elements by std::shared_ptr and shares ownership with all its copies.
- A range type that generates its elements on demand, e.g., std::ranges::iota_view.
A copyable container such as std::vector<std::string> generally does not meet the semantic requirements of view since copying the container copies all of the elements, which cannot be done in constant time.
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 will not have unexpected complexity.
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.
[edit] Example
A minimum view.
#include struct ArchetypalView : std::ranges::view_interface { int* begin(); int* end(); }; static_assert(std::ranges::view);
[edit] 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 |