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 типа класса. Для наглядности, неквалифицированная версия его типа обозначается как __rend_fn.
Все экземпляры __rend_fn равны. Эффекты вызова различных экземпляров типа __rend_fn на одних и тех же аргументах эквивалентны, независимо от того, является ли выражение, обозначающее экземпляр, lvalue или rvalue, и квалифицировано ли оно как const или нет (хотя экземпляр с квалификатором volatile не обязан быть вызываемым). Таким образом, ranges::rend можно свободно копировать, а его копии могут использоваться взаимозаменяемо.
Учитывая набор типов Args..., если std::declval<Args>()... удовлетворяют требованиям аргументов для ranges::rend выше, __rend_fn моделирует
-
std::invocable<__rend_fn, Args...>, -
std::invocable<const __rend_fn, Args...>, -
std::invocable<__rend_fn&, Args...>, и -
std::invocable<const __rend_fn&, Args...>.
В противном случае, ни один оператор вызова функции __rend_fn не участвует в разрешении перегрузки.
Примечания
Если аргумент является 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, значение возврата создавалось с помощью move-конструктора из объекта-временной переменной. Все реализации непосредственно возвращают 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/w/cpp/ranges/rend