std::ranges::rbegin
Определено в заголовке <ranges> | ||
|---|---|---|
Определено в заголовке <iterator> | ||
inline namespace /* unspecified */ {
inline constexpr /* unspecified */ rbegin = /* unspecified */;
}
| (начиная с C++20) (объект точки настройки) | |
| Сигнатура вызова | ||
template< class T >
requires /* see below */
constexpr std::input_or_output_iterator auto rbegin( T&& t );
| (начиная с C++20) |
Возвращает итератор на последний элемент аргумента.
Если T является типом массива, а std::remove_all_extents_t<std::remove_reference_t<T>> является неполным типом, вызов ranges::rbegin некорректен; диагностика не требуется.
Если аргумент является lvalue или ranges::enable_borrowed_range<std::remove_cv_t<T>> является true, то вызов ranges::rbegin эквивалентен по выражению следующему:
-
decay-copy(t.rbegin())(до C++23)auto(t.rbegin())(начиная с C++23), если это выражение корректно и его тип моделируетstd::input_or_output_iterator. - В противном случае —
decay-copy(rbegin(t))(до C++23)auto(rbegin(t))(начиная с C++23), еслиTявляется типом класса или перечисления, это выражение корректно и его тип моделируетstd::input_or_output_iterator, причём смыслrbeginопределяется так, как если бы выполнялся только поиск, зависящий от аргументов. - В противном случае —
std::make_reverse_iterator(ranges::end(t)), еслиranges::begin(t)иranges::end(t)являются корректными выражениями, имеют одинаковый тип, и этот тип моделируетstd::bidirectional_iterator.
Во всех остальных случаях вызов ranges::rbegin некорректен, что может привести к ошибке подстановки, если ranges::rbegin(t) появляется в непосредственном контексте инстанцирования шаблона.
Объекты точек настройки
Имя ranges::rbegin обозначает объект точки настройки — константный функциональный объект типа класса, который является литеральным semiregular. Подробности см. в разделе CustomizationPointObject.
Примечания
Если аргумент является rvalue (то есть T является типом объекта), а ranges::enable_borrowed_range<std::remove_cv_t<T>> является false, вызов ranges::rbegin некорректен, что также приводит к ошибке подстановки.
Во всех случаях возвращаемый тип моделирует std::input_or_output_iterator.
Стандарт C++20 требует, чтобы, если лежащий в основе вызов функции rbegin возвращает prvalue, возвращаемое значение конструировалось перемещением из материализованного временного объекта. Все реализации вместо этого непосредственно возвращают prvalue. Это требование исправлено предложением, принятым после C++20, P0849R8, чтобы привести стандарт в соответствие с реализациями.
Пример
#include <iostream>
#include <ranges>
#include <span>
#include <vector>
int main()
{
std::vector<int> v = {3, 1, 4};
auto vi = std::ranges::rbegin(v);
std::cout << *vi << '\n';
*vi = 42; // OK
int a[] = {-5, 10, 15};
auto ai = std::ranges::rbegin(a);
std::cout << *ai << '\n';
*ai = 42; // OK
// auto x_x = std::ranges::rbegin(std::vector{6, 6, 6});
// ill-formed: the argument is an rvalue (see Notes ↑)
auto si = std::ranges::rbegin(std::span{a}); // OK
static_assert(std::ranges::enable_borrowed_range<
std::remove_cv_t<decltype(std::span{a})>>);
*si = 42; // OK
}
Вывод:
4 15
Отчёты об ошибках
Следующие отчёты об ошибках, изменяющие поведение, были ретроактивно применены к ранее опубликованным стандартам C++.
| DR | Применён к | Опубликованное поведение | Исправленное поведение |
|---|---|---|---|
| P2602R2 | C++20 | предусмотрен механизм, запрещающий некоторые функции rbegin, не являющиеся членами класса и найденные с помощью ADL | такой механизм удалён |
См. также
|
(C++20) | возвращает обратный итератор для диапазона только для чтения (объект точки настройки) |
|
(C++14) | возвращает обратный итератор на начало контейнера или массива (шаблон функции) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/ranges/rbegin