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

168

Chapter 6: Ranges and Views

6.6Summary of All Container Idioms Broken By Views

As documented in this chapter, several idioms that we we can count on when using containers are broken by views. Here is a quick summary you should always take into account when using generic code for both containers and views:

• You might not be able to iterate over the elements of a standard view when it is const.

As a consequence, generic code for all kinds of ranges (containers and views) has to declare the parameters as universal/forwarding references.

However, do not use universal/forwarding references when you have concurrent iterations. In that case, const is your friend.

• Standard views on lvalue ranges do not propagate constness.

This means that declaring such a view as const does not declare the elements to be const.

Concurrent iterations over standard views might cause data races (a runtime error due to undefined behavior) even if they only read.

Reading iterations might affect later functional behavior or even invalidate later iterations.

Use standard views ad hoc.

Copying a view might create a view with different states and behavior than the source view. Avoid copying standard views.

cbegin() and cend() might not make elements const.

This will partially be fixed with C++23 by providing cbegin() and cend() member functions and fixing std::ranges::cbegin() and std::ranges::cend(). Unfortunately, std::cbegin() and std::cend() will still be broken.

Type const_iterator is usually not available.

For C++23, the following breakage is planned: for some standard views, declaring the elements as const might have no effect. You might be able to modify the members of a const element of a view.

This means that a standard view is not always a pure subset that restricts or deals with the elements of a range; it might provide options and operations that are not allowed for when using the range as a whole instead.

As a consequence, use views ad hoc and with care and forget about any temporary constness. Honestly, you might consider avoiding standard views and using something with a safer design instead.

6.7Afternotes

After adopting the Standard Template Llibrary for the first C++ standard, which introduced a pair of iterators as abstraction for containers/collections to deal with them in algorithms, there was always an ongoing discussion about how to deal with a single range object instead of passing begin iterators and end iterators. The Boost.Range library and the Adobe Source Libraries (ASL) were two early approaches that came up with concrete libraries.

The first proposal for ranges becoming a C++ standard was in 2005 by Thorsten Ottosen in http:// wg21.link/n1871. Eric Niebler took on the task of driving this forward over years (supported by many other people), which resulted in another proposal in 2014 by Eric Niebler, Sean Parent, and Andrew Sutton in http://wg21.link/n4128 (this document contains the rationale for many key design decisions). As a

6.7 Afternotes

169

consequence, in October 2015, a Ranges Technical Specification was opened starting with http://wg21. link/n4560.

The ranges library was finally adopted by merging the Ranges TS into the C++ standard as proposed by Eric Niebler, Casey Carter, and Christopher Di Bella in http://wg21.link/p0896r4.

After adoption, several proposals, papers, and even defects against C++20 changed significant aspects, especially for views. See, for example, http://wg21.link/p2210r2 (fixing split views), http://wg21. link/p2325r3 (fixing the definition of views), http://wg21.link/p2415r2 (introducing owning views for rvalue ranges), and http://wg21.link/p2432r1 (fixing istream views) proposed by Barry Revzin, Tim Song, and Nicolai Josuttis.

In addition, note that at least some of the several const issues with views will probably be fixed in C++23 with http://wg21.link/p2278r4. Hopefully, vendors will provide that fix before C++23 because otherwise, C++20 code might not be compatible with C++23 here.

170

This page is intentionally left blank