Home » Посмотреть классы | Майкрософт учиться

Посмотреть классы | Майкрософт учиться

<!– –>

А Посмотреть это упрощенный диапазон, который ссылается на элементы, которые ему не принадлежат, за исключением owning_view). Представление обычно основано на другом диапазоне и обеспечивает другой способ его просмотра путем преобразования или фильтрации. Например, std::views::filter — это представление, использующее заданные вами критерии для выбора элементов из другого диапазона.

Когда вы получаете доступ к элементам в представлении, это делается «лениво», поэтому работа выполняется только тогда, когда вы получаете элемент. Это также позволяет комбинировать или «составлять» представления без потери производительности. Например, вы можете создать представление, предоставляющее только четные элементы из диапазона, а затем преобразовать их, возведя их в квадрат. Работа по фильтрации и преобразованию выполняется только для элементов, к которым вы обращаетесь, и только тогда, когда вы к ним обращаетесь.

Представление можно копировать, назначать и уничтожать за постоянное время, независимо от того, сколько элементов оно содержит. Это связано с тем, что представление не владеет элементами, на которые оно ссылается, поэтому ему не нужно делать копию. По этой же причине вы можете создавать представления без потери производительности.

Обычно представление создается с помощью адаптера диапазона. Адаптеры диапазона — это предполагаемый способ создания представления, их проще использовать, чем непосредственное создание экземпляров классов представлений, и иногда они более эффективны, чем непосредственное создание экземпляров классов представлений. Классы представлений предоставляются непосредственно в первую очередь в том случае, если вам нужно создать собственный настраиваемый тип представления на основе существующего типа представления.

Вот краткий пример создания представления квадратов элементов, которые делятся на 3 в векторе:

// requires /std:c++20 or later
#include 
#include 
#include 

int main()
{
    std::vector input =  {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    auto divisible_by_three = [](const int n) {return n % 3 == 0;};
    auto square = [](const int n) {return n * n;};

    auto x = input | std::views::filter(divisible_by_three)
               | std::views::transform(square);

    for (int i : x)
    {
        std::cout << i << ' '; // 0 9 36 81
    }
}
0 9 36 81

Использование представления после изменения диапазона, на котором оно основано, может привести к неопределенному поведению. Например, reverse_view на основе вектора не следует повторно использовать, если вы добавляете/удаляете элементы из базового вектора. Изменение базового вектора делает недействительным контейнер end iterator — включая копию итератора, которую могло создать представление.

Поскольку представления недороги в создании, вам обычно следует пересоздавать представление, если вы изменяете базовый диапазон. Следующий пример демонстрирует это, а также показывает, как сохранить конвейер представления в переменной, чтобы вы могли повторно использовать его:

// requires / std:c++20 or later
#include 
#include 
#include 
#include 
#include 
#include 

template
void show(std::string_view msg, rangeType r)
{
    std::cout << msg;
    std::ranges::for_each(r,
        [](auto e)
        {
            std::cout << e << ' ';
        });
    std::cout << 'n';
}

int main()
{
    std::vector v{ 1, 2, 3, 4 };
    show("v: ", v);

    // You can save a view pipeline
    auto rev3 = std::views::take(3) | std::views::reverse;

    show("v | rev3: ", v | rev3); // 3 2 1

    v.insert(v.begin(), 0); // v = 0 1 2 3 4
    show("v: ", v);

    // Because modifying the vector invalidates its iterators, rebuild the view.
    // We are reusing the view pipeline we saved earlier
    show("v | rev3(v): ", rev3(v));
}
v: 1 2 3 4
v | rev3: 3 2 1
v: 0 1 2 3 4
v | rev3(v): 2 1 0

Следующие классы представлений определены в std::ranges пространство имен.

Адаптер диапазона Описание
basic_istream_viewС++ 20 Представление последовательных элементов из входного потока.
common_viewС++ 20 Адаптирует представление с другими типами итераторов/стражей в представление с теми же типами итераторов/стражей.
drop_viewС++ 20 Создано из другого представления, пропустив первое count элементы.
drop_while_viewС++ 20 Создано из другого представления, пропуская ведущие элементы, пока сохраняется предикат.
elements_viewС++ 20 Представление выбранного индекса для каждого кортежеподобного значения в коллекции. Например, учитывая диапазон std::tuple значений, создайте представление, состоящее из всех string элементы из каждого кортежа.
empty_viewС++ 20 Вид без элементов.
filter_viewС++ 20 Отфильтровывает элементы диапазона, не соответствующие предикату.
iota_viewС++ 20 Сгенерированное представление, содержащее последовательность возрастающих значений.
join_viewС++ 20 Объединяет все элементы нескольких диапазонов в единое представление.
keys_viewС++ 20 Представление по первому индексу каждого кортежеподобного значения в коллекции. Например, учитывая диапазон std::tuple значений, создайте представление, состоящее из string элементы из каждого кортежа.
lazy_split_viewС++ 20 Разбивает представление на поддиапазоны на основе разделителя.
owning_viewС++ 20 Становится владельцем элементов из другого диапазона.
ref_viewС++ 20 Представление, которое ссылается на элементы, принадлежащие другому диапазону.
reverse_viewС++ 20 Представляет элементы диапазона в обратном порядке.
single_viewС++ 20 Представление, содержащее только один элемент.
split_viewС++ 20 Разбивает представление на поддиапазоны на основе разделителя.
subrangeС++ 20 Представление части элементов диапазона, как определено начальным итератором и дозорным.
take_viewС++ 20 Содержит указанное количество элементов, взятых из начала диапазона.
take_while_viewС++ 20 Содержит ведущие элементы диапазона, соответствующие заданному предикату.
transform_viewС++ 20 Представление базовой последовательности после применения функции преобразования к каждому элементу.
values_viewС++ 20 Представление второго индекса в каждом кортежеподобном значении в коллекции. Например, учитывая диапазон std::tuple значений, создайте представление, состоящее из int элементы из каждого кортежа.

Многие из этих классов имеют соответствующие range-adaptors в std:views пространство имен, которое их создает. Отдайте предпочтение адаптерам в std::views для непосредственного создания классов представлений. Адаптеры диапазона являются предполагаемыми точками доступа, они проще в использовании и в некоторых случаях более эффективны.

Посмотреть характеристики классов

Каждая тема класса просмотра имеет Характеристики раздел, следующий за разделом синтаксиса. Характеристики раздел имеет следующие записи:

  • Адаптер диапазона: Ссылка на адаптер диапазона, создающий представление. Обычно вы используете адаптер диапазона для создания представления, а не создаете класс представления напрямую, поэтому он указан здесь для удобства.
  • Базовый диапазон: Представления имеют разные требования к итератору для типа базового диапазона, который они могут использовать. В таблице ниже представлена ​​иерархия итераторов.
  • Посмотреть категорию итератора: Категория итератора представления. Когда представление адаптирует диапазон, тип итератора для представления обычно совпадает с типом итератора базового диапазона. Однако для некоторых представлений он может отличаться. Например, reverse_view имеет bidirectional_iterator категории, даже если базовый диапазон имеет random_access_iterator категория.
  • Тип элемента: Тип элементов, возвращаемых итератором представления.
  • Размер: Может ли представление возвращать количество элементов, на которые оно ссылается. Не все представления могут.
  • Общий диапазон: Указывает, является ли представление common_range, что означает, что типы итератора начала и сторожевого элемента совпадают. Общие диапазоны полезны для кода предварительного диапазона, который работает с парами итераторов. Например, конструкторы пары итераторов контейнера последовательности, такие как vector(ranges::begin(x), ranges::end(x)).
  • Заимствованный диапазон: Указывает, является ли представление заимствованный диапазон. borrowed_range означает, что вы можете использовать итераторы для T после T уничтожен. Ни один стандартный контейнер не является заимствованным диапазоном, поскольку уничтожение контейнера освобождает элементы, поэтому любые итераторы становятся недействительными. В этом случае мы говорим, что итераторы остаются «висящими» после уничтожения. Например,std::ranges::find() обычно возвращает итератор к найденному элементу в аргументе диапазона. Если аргумент диапазона является временным (rvalue) контейнером, будет ошибкой сохранять возвращенный итератор и использовать его позже, потому что он «висит». Алгоритмы диапазона, которые возвращают итераторы (или поддиапазоны), делают это только в том случае, если их аргументы являются lvalue (не временными) или заимствованными диапазонами. В противном случае они возвращают std::dangling объект, который в сообщениях об ошибках дает подсказку о том, что пошло не так, если вы попытаетесь использовать его как итератор.
  • Является const повторяемый: Указывает, можете ли вы перебирать const экземпляр вида. Не все const просмотры могут повторяться. Если вид не const-iterable, вы не можете выполнять итерацию с for (const auto& element : as_const(theView)) или передать его функции, которая принимает константную ссылку на представление, а затем пытается выполнить итерацию по нему.

Итераторная иерархия

Категория итераторов, упомянутая в Характеристики раздел по Адаптер диапазона а также Посмотреть категорию итератора относится к иерархии итераторов, поддерживаемых диапазонами и представлениями.

Эта иерархия в порядке возрастания возможностей выглядит следующим образом:

категория итератора диапазона Описание
output_range Только запись, только продвижение вперед; один проход
input_range Только движется вперед; один проход
forward_range Только движется вперед; многоходовой
bidirectional_range Может двигаться вперед и назад; многоходовой.
random_access_range Может получить доступ к коллекции с помощью индекса; многоходовой.
contiguous_range Может получить доступ к коллекции с помощью индекса, а элементы хранятся в памяти непрерывно.

Итератор также имеет возможности итераторов, предшествующих ему в таблице. Например, bidirectional_range можно использовать с forward_range итератор, но не наоборот.

Заявление «требует input_range или лучше” означает, что представление можно использовать с input_range, forward_range, bidirectional_range, random_access_rangeили же contiguous_range итератор, потому что любая из этих категорий так же эффективна, как input_range.

Смотрите также


range-adaptors

Read more:  Business Journal ищет номинантов на девятую ежегодную премию «Самые уважаемые генеральные директора»

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.