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 задаёт требования к типу range, обладающему подходящими семантическими свойствами для использования при построении конвейеров адаптеров диапазонов.enable_view используется для указания того, является ли range представлением 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 для типов, которые ему не соответствуют. Такие специализации должны быть пригодны для использования в константных выражениях и иметь тип constbool.
Семантические требования
1)T моделирует view только если: - перемещающее конструирование
Tимеет постоянную временную сложность, и - если из объекта
T, содержащего \(\scriptsize M\)M элементов, создаётся \(\scriptsize N\)N его копий и/или перемещений, то уничтожение этих \(\scriptsize N\)N объектов имеет сложность \(\scriptsize \mathcal{O}{(N+M)}\)𝓞(N+M) (что подразумевает, что уничтожение перемещённого объектаviewимеет сложность \(\scriptsize \mathcal{O}{(1)}\)𝓞(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_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++.
| Отчёт об ошибке | Применяется к | Опубликованное поведение | Корректное поведение |
|---|---|---|---|
| P2325R3 | C++20 |
view требовал default_initializable | не требует |
| LWG 3549 | C++20 |
enable_view не обнаруживал наследование от view_interface | обнаруживает |
| P2415R2 | C++20 | ограничение на временную сложность уничтожения было слишком строгим | смягчено |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/ranges/view