Spec-Zone.ru › C++

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 этот механизм удалён

См. также

ranges::ssize
(C++20)
возвращает целое число со знаком, равное размеру диапазона
(объект точки настройки)
ranges::sized_range
(C++20)
указывает, что диапазон может узнать свой размер за постоянное время
(концепт)
ranges::distance
(C++20)
возвращает расстояние между итератором и сентинелом либо между началом и концом диапазона
(функциональный объект алгоритма)
sizessize
(C++17)(C++20)
возвращает размер контейнера или массива
(шаблон функции)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/ranges/size

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API