Namespaces
Variants

std::ranges::rend

From ru.cppreference.net
 
 
Библиотека диапазонов
Адаптеры диапазонов
 
Определён в заголовке <ranges>
Определён в заголовке <iterator>
inline namespace /* unspecified */ {
    inline constexpr /* unspecified */ rend = /* unspecified */;
}
(начиная с C++20)
(объект точки настройки)
Сигнатура вызова
template< class T >
    requires /* see below */
constexpr std::sentinel_for<
    decltype(ranges::rbegin(std::declval<T>()))> auto rend( T&& t );
(начиная с C++20)

Возвращает страж, указывающий на конец перевёрнутого диапазона.

Если T — это тип массива, а std::remove_all_extents_t<std::remove_reference_t<T>> является неполным, то вызов ranges::rend считается некорректным, диагностика не требуется.

Если аргумент является lvalue или ranges::enable_borrowed_range<std::remove_cv_t<T>> является true, то вызов ranges::rend является эквивалентным выражению:

  1. decay-copy(t.rend())(до C++23)auto(t.rend())(начиная с C++23), если это выражение допустимо и его тип соответствует std::sentinel_for<decltype(ranges::rbegin(std::declval<T>()))>.
  2. В противном случае, decay-copy(rend(t))(до C++23)auto(rend(t))(начиная с C++23), если T — это тип класса или перечисления, это выражение допустимо и его тип соответствует std::sentinel_for<decltype(ranges::rbegin(std::declval<T>()))>, при этом значение rend определяется так, как если бы был выполнен поиск, зависимый от аргументов только.
  3. В противном случае, std::make_reverse_iterator(ranges::begin(t)) если и ranges::begin(t), и ranges::end(t) являются допустимыми выражениями, имеют один и тот же тип, и этот тип соответствует std::bidirectional_iterator.

Во всех остальных случаях вызов ranges::rend является некорректным, что может привести к ошибке подстановки, когда ranges::rend(t) появляется в непосредственном контексте инстанцирования шаблона.

Объекты точек кастомизации

Имя ranges::rend обозначает объект точки кастомизации , который является константным функциональным объектом типа литерального semiregular класса. Для подробностей см. CustomizationPointObject .

Примечания

Если аргумент является rvalue (т.е. T является объектным типом) и ranges:: enable_borrowed_range < std:: remove_cv_t < T >> равно false , или если он является массивом неизвестной длины, вызов ranges::rend является некорректным, что также приводит к ошибке подстановки.

Если ranges :: rend ( std:: forward < T > ( t ) ) корректен, тогда decltype ( ranges :: rend ( std:: forward < T > ( t ) ) ) и decltype ( ranges:: begin ( std:: forward < T > ( t ) ) ) моделируют std::sentinel_for во всех случаях, тогда как T моделирует std::ranges::range .

Стандарт C++20 требует, чтобы если базовый вызов функции rend возвращает prvalue, возвращаемое значение создается перемещением из материализованного временного объекта. Все реализации напрямую возвращают prvalue вместо этого. Требование исправлено пост-C++20 предложением P0849R8 для соответствия реализациям.

Пример

#include <algorithm>
#include <iostream>
#include <ranges>
#include <vector>
int main()
{
    std::vector<int> v = {3, 1, 4};
    namespace ranges = std::ranges;
    if (ranges::find(ranges::rbegin(v), ranges::rend(v), 5) != ranges::rend(v))
        std::cout << "found a 5 in vector v!\n";
    int a[] = {5, 10, 15};
    if (ranges::find(ranges::rbegin(a), ranges::rend(a), 5) != ranges::rend(a))
        std::cout << "found a 5 in array a!\n";
}

Вывод:

found a 5 in array a!

Отчеты о дефектах

Следующие отчеты об изменениях поведения, влияющие на дефекты, были применены ретроактивно к ранее опубликованным стандартам C++.

DR Applied to Behavior as published Correct behavior
P2602R2 C++20 there's machinery to prohibit certain non-member rend found by ADL removed such machinery

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

возвращает обратный конечный итератор для диапазона только для чтения
(объект точки кастомизации)
возвращает обратный итератор для диапазона
(объект точки кастомизации)
(C++14)
возвращает обратный конечный итератор для контейнера или массива
(шаблон функции)