std::ranges::view, std::ranges::enable_view, std::ranges::view_base
| Определён в заголовке <ranges>
|
||
template<class T>
concept view = ranges::range<T> && std::movable<T> && ranges::enable_view<T>;
|
(1) | (начиная с C++20) |
template<class T>
constexpr bool enable_view =
std::derived_from<T, view_base> || /*is-derived-from-view-interface*/<T>;
|
(2) | (начиная с C++20) |
struct view_base { };
|
(3) | (начиная с C++20) |
view определяет требования к типу диапазона, который обладает подходящими семантическими свойствами для использования при построении конвейеров адаптеров диапазонов.enable_view используется для указания, является ли диапазон представлением (view). /*is-derived-from-view-interface*/<T> равен true тогда и только тогда, когда T имеет ровно один открытый базовый класс ranges::view_interface<U> для некоторого типа U, и T не имеет базовых классов типа ranges::view_interface<V> ни для какого другого типа V.
Пользователи могут специализировать enable_view как true для cv-неквалифицированных определённых пользователем типов, которые моделируют view, и false для типов, которые этого не делают. Такие специализации должны быть пригодными для использования в константных выражениях и иметь тип const bool.
Семантические требования
T
моделирует
view
только если:
-
перемещающее конструирование
Tимеет постоянную временную сложность, и -
если из объекта
Tсодержащего M элементов сделано N копий и/или перемещений, тогда эти N объектов имеют 𝓞(N+M) деструкцию (что подразумевает, что перемещённый объектviewимеет 𝓞(1) деструкцию), и -
либо
std::
copy_constructible
<
T
>
равно
false
, либо копирующее конструирование
Tимеет постоянную временную сложность, и -
либо
std::
copyable
<
T
>
равно
false
, либо копирующее присваивание
Tимеет не большую временную сложность, чем деструкция с последующим копирующим конструированием.
Специализации
Специализации
enable_view
для всех специализаций следующих стандартных шаблонов определены как
true
:
| (начиная с C++26) |
Примечания
Примеры типов
view
:
-
Тип
range, который оборачивает пару итераторов, например, std :: ranges:: subrange < I > . -
Тип
range, который хранит свои элементы через std::shared_ptr и разделяет владение со всеми своими копиями. -
Тип
range, который генерирует свои элементы по требованию, например, std::ranges::iota_view .
Копируемый контейнер, такой как
std::
vector
<
std::
string
>
, обычно не удовлетворяет семантическим требованиям
view
, поскольку копирование контейнера копирует все элементы, что не может быть выполнено за константное время.
Хотя изначально представления описывались как дешёво копируемые и невладеющие диапазоны, тип не обязан быть копируемым или невладеющим для моделирования
view
. Однако он всё равно должен быть дешёвым для копирования (если он копируемый), перемещения, присваивания и уничтожения, чтобы
адаптеры диапазонов
не имели неожиданной сложности.
По умолчанию тип, моделирующий
movable
и
range
, считается представлением (view), если он публично и однозначно унаследован от
view_base
или ровно одной специализации
std::ranges::view_interface
.
Пример
Минимальное представление.
#include <ranges> struct ArchetypalView : std::ranges::view_interface<ArchetypalView> { int* begin(); int* end(); }; static_assert(std::ranges::view<ArchetypalView>);
` сохранены в оригинальном виде.
Отчеты о дефектах
Следующие отчеты об изменениях поведения, влияющие на дефекты, были применены ретроактивно к ранее опубликованным стандартам C++.
| DR | Применяется к | Поведение в опубликованной версии | Корректное поведение |
|---|---|---|---|
| P2325R3 | C++20 |
view
требовал
default_initializable
|
не требует |
| LWG 3549 | C++20 |
enable_view
не обнаруживал наследование от
view_interface
|
обнаруживает |
| P2415R2 | C++20 | ограничение на временную сложность деструкции было слишком строгим | ослаблено |