std::ranges::size
Определено в заголовке <ranges> | ||
|---|---|---|
Определено в заголовке <iterator> | ||
inline namespace /* unspecified */ {
inline constexpr auto size = /* unspecified */;
}
| (начиная с C++20) (объект точки настройки) | |
| Сигнатура вызова | ||
template< class T >
requires /* see below */
constexpr auto size( T&& t );
| (начиная с C++20) |
Вычисляет количество элементов в t за постоянное время.
Пусть t обозначает подвыражение, результатом которого является (возможно, материализованный) объект E, а тип E обозначен как T:
- Если
Tявляется массивом неизвестного размера,ranges::size(E)некорректно. - В противном случае, если
Tявляется типом массива,ranges::size(E)эквивалентно выражениюdecay-copy (std::extent_v<T>)(до C++23)auto(std::extent_v<T>)(начиная с C++23). - В противном случае, если выполнены все следующие условия,
ranges::size(E)эквивалентно выражениюdecay-copy (t.size())(до C++23)auto(t.size())(начиная с C++23):-
ranges::disable_sized_range<std::remove_cv_t<T>>являетсяfalse. -
decay-copy (t.size())(до C++23)auto(t.size())(начиная с C++23) является допустимым выражением целочисленного типа.
-
- В противном случае, если выполнены все следующие условия,
ranges::size(E)эквивалентно выражениюdecay-copy (size(t))(до C++23)auto(size(t))(начиная с C++23):-
Tявляется типом класса или перечисления. -
ranges::disable_sized_range<std::remove_cv_t<T>>являетсяfalse. -
decay-copy (size(t))(до C++23)auto(size(t))(начиная с C++23) является допустимым выражением целочисленного типа, причём значениеsizeопределяется так, как если бы выполнялся только поиск, зависящий от аргументов.
-
- В противном случае, если выполнены все следующие условия,
ranges::size(E)эквивалентно выражениюto-unsigned-like (ranges::end(t)-ranges::begin(t)):-
Tмоделируетforward_range. - Пусть тип
ranges::begin(t)обозначен какI, а типranges::end(t)— какS; моделируются оба требования:sized_sentinel_for<S,I> иforward_iterator<I>. -
to-unsigned-like (ranges::end(t)-ranges::begin(t))является допустимым выражением.
-
- В противном случае
ranges::size(E)некорректно.
В диагностируемых случаях некорректного кода, описанных выше, возникает ошибка подстановки, если ranges::size(E) появляется в непосредственном контексте инстанцирования шаблона.
Объекты точек настройки
Имя ranges::size обозначает объект точки настройки — константный функциональный объект типа класса литерального semiregular. Подробнее см. CustomizationPointObject.
Примечания
Если ranges::size(e) допустимо для выражения e, возвращаемый тип является целочисленным.
Стандарт C++20 требует, чтобы, если нижележащий вызов функции size возвращает prvalue, возвращаемое значение конструировалось перемещением из материализованного временного объекта. Все реализации вместо этого напрямую возвращают prvalue. Это требование исправлено предложением, принятым после C++20, P0849R8, чтобы привести стандарт в соответствие с реализациями.
Выражение ranges::distance(e) также можно использовать для определения размера диапазона e. В отличие от ranges::size(e), ranges::distance(e) работает, даже если e является диапазоном без известного размера, однако в этом случае имеет линейную сложность.
Пример
#include <iostream>
#include <ranges>
#include <type_traits>
#include <vector>
int main()
{
auto v = std::vector<int>{};
std::cout << "ranges::size(v) == " << std::ranges::size(v) << '\n';
auto il = {7}; // std::initializer_list
std::cout << "ranges::size(il) == " << std::ranges::size(il) << '\n';
int array[]{4, 5}; // array has a known bound
std::cout << "ranges::size(array) == " << std::ranges::size(array) << '\n';
static_assert(std::is_signed_v<decltype(std::ranges::size(v))> == false);
}
Вывод:
ranges::size(v) == 0 ranges::size(il) == 1 ranges::size(array) == 2
Отчёты об ошибках
Следующие отчёты об ошибках, меняющие поведение, были ретроактивно применены к ранее опубликованным стандартам C++.
| DR | Применяется к | Поведение согласно опубликованной версии | Исправленное поведение |
|---|---|---|---|
| P2602R2 | C++20 | существовал механизм, запрещающий некоторые не являющиеся членами класса size, найденные с помощью ADL | этот механизм удалён |
См. также
|
(C++20) | возвращает целое число со знаком, равное размеру диапазона (объект точки настройки) |
|
(C++20) | указывает, что диапазон может узнать свой размер за постоянное время (концепт) |
|
(C++20) | возвращает расстояние между итератором и сентинелом либо между началом и концом диапазона (функциональный объект алгоритма) |
|
(C++17)(C++20) | возвращает размер контейнера или массива (шаблон функции) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/ranges/size