std::ranges::rend
Определено в заголовочном файле <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 эквивалентен выражению:
-
decay-copy(t.rend())(до C++23)auto(t.rend())(начиная с C++23), если это выражение корректно и его тип моделируетstd::sentinel_for<decltype(ranges::rbegin(std::declval<T>()))>. - В противном случае —
decay-copy(rend(t))(до C++23)auto(rend(t))(начиная с C++23), еслиTявляется типом класса или перечисления, это выражение корректно и его тип моделируетstd::sentinel_for<decltype(ranges::rbegin(std::declval<T>()))>, при этом смыслrendустанавливается так, как если бы выполнялся только поиск с учетом аргументов. - В противном случае —
std::make_reverse_iterator(ranges::begin(t)), еслиranges::begin(t)иranges::end(t)являются корректными выражениями, имеют одинаковый тип, и этот тип моделируетstd::bidirectional_iterator.
Во всех остальных случаях вызов ranges::rend некорректен, что может привести к ошибке подстановки, если ranges::rend(t) встречается в непосредственном контексте инстанцирования шаблона.
Объекты точек настройки
Имя ranges::rend обозначает объект точки настройки — константный функциональный объект типа класса, являющегося литеральным semiregular. Подробности см. в разделе Объект точки настройки.
Примечания
Если аргумент является 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. Это требование исправлено предложением P0849R8, принятым после C++20, чтобы привести стандарт в соответствие с реализациями.
Пример
#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 | Применяется к | Поведение согласно опубликованной версии | Правильное поведение |
|---|---|---|---|
| P2602R2 | C++20 | существуют механизмы, запрещающие определённые нечленские rend, найденные с помощью ADL | такие механизмы удалены |
См. также
|
(C++20) | возвращает обратный итератор конца для диапазона только для чтения (объект точки настройки) |
|
(C++20) | возвращает обратный итератор для диапазона (объект точки настройки) |
|
(C++14) | возвращает обратный итератор конца контейнера или массива (шаблон функции) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/ranges/rend