Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
josuttis_nm_c20_the_complete_guide.pdf
Скачиваний:
44
Добавлен:
27.03.2023
Размер:
5.85 Mб
Скачать

7.2 New Iterator Categories

177

std::list<int> lst {1, 2, 3, 4, 5, 6, 7, 8, 9};

auto vt = std::views::take(lst, 5); // begin() and end() have different types

auto v4 = std::views::common(vt); // std::ranges::common_view<decltype(vt)>

Note that both the constructors of a std::ranges::common_view and the helper type std::common:iterator require that passed iterators have different types. Therefore, you should use this adaptor if you do not know whether iterator types differ.

7.2New Iterator Categories

Iterators have different abilities. These abilities are important because some algorithms require special iterator abilities. For example, sorting algorithms require iterators that can perform random access because otherwise, the performance would be poor. For this reason, iterators have different categories, which were extended in C++20 by a new category: contiguous iterator. The abilities of these categories are listed in table Iterator categories.

Iterator Category

Ability

Providers

 

 

 

Output

Writes forward

ostream iterator, inserter

 

Input

Reads forward once

istream iterator

 

 

Forward

Reads forward

std::forward_list<>, unordered containers

Bidirectional

Reads forward and backward

list<>,

set<>,

multiset<>,

map<>,

 

 

multimap<>

 

 

Random-access

Reads with random access

deque<>

 

 

 

Contiguous

Reads elements stored in

array<>, vector<>, string, C-style array

 

contiguous memory

 

 

 

 

 

 

 

 

 

 

 

Table 7.1. Iterator categories

 

 

 

Note that significant details of the categories changed with C++20. The most important changes are:

The new iterator category contiguous. For this category, a new iterator tag type is defined: std::contiguous_iterator_tag.

Iterators that yield temporary objects (prvalues) can now have a stronger category than input iterators. The requirement to yield references no longer applies to forward iterators.

Input iterators are no longer guaranteed to be copyable. You should only move them around.

Postfix increment operators of input iterators are no longer required to yield anything. For an input iterator pos, you should no longer use pos++. Use ++pos instead.

These changes are not backward compatible:

A check whether an iterator is a random-access iterator is no longer true for iterators of containers like std::vector or arrays. Instead, you have to check whether the iterator supports random access.

The assumption that the values of forward, bidirectional, or random-access iterators are references no longer always applies.

For that reason, C++20 introduces a new optional iterator attribute, iterator_concept, and defines that this attribute may be set to signal a C++20 category that differs from the traditional category. For example: