Scroll to navigation

std::ranges::size(3) C++ Standard Libary std::ranges::size(3)

NAME

std::ranges::size - std::ranges::size

Synopsis


Defined in header <ranges>
Defined in header <iterator>
inline namespace /* unspecified */ {
(since C++20)
inline constexpr auto size = /* unspecified */; (customization point object)


}
Call signature
template< class T >


requires /* see below */ (since C++20)


constexpr auto size( T&& t );


Calculates the number of elements in t in constant time.


A call to ranges::size is expression-equivalent to:


1. decay-copy(std::extent_v<T>)
(until C++23)
auto(std::extent_v<T>)
(since C++23), if T is an array type with a known bound.
2. Otherwise,
decay-copy(t.size())
(until C++23)
auto(t.size())
(since C++23), if ranges::disable_sized_range<std::remove_cv_t<T>> is false, and
that expression is valid and has an integer-like type.
3. Otherwise,
decay-copy(size(t))
(until C++23)
auto(size(t))
(since C++23), if ranges::disable_sized_range<std::remove_cv_t<T>> is false, and
the converted expression is valid and has an integer-like type, where the
meaning of size is established as if by performing argument-dependent lookup
only.
4. Otherwise, /* to-unsigned-like */(ranges::end(t) - ranges::begin(t)), if T
models ranges::forward_range and ranges::sentinel_t<T> models
std::sized_sentinel_for<ranges::iterator_t<T>>,


where /* to-unsigned-like */ denotes an explicit conversion to an
unsigned-integer-like type.


In all other cases, a call to ranges::size is ill-formed, which can result in
substitution failure when ranges::size(t) appears in the immediate context of a
template instantiation.

Notes


Whenever ranges::size(e) is valid for an expression e, the return type is
integer-like.


The C++20 standard requires that if the underlying size function call returns a
prvalue, the return value is move-constructed from the materialized temporary
object. All implementations directly return the prvalue instead. The requirement is
corrected by the post-C++20 proposal P0849R8 to match the implementations.


The expression ranges::distance(e) can also be used to determine the size of a range
e. Unlike ranges::size(e), ranges::distance(e) works even if e is an unsized range,
at the cost of having linear complexity in that case.

Example

// Run this code


#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);
}

Output:


ranges::size(v) == 0
ranges::size(il) == 1
ranges::size(array) == 2


Defect reports


The following behavior-changing defect reports were applied retroactively to
previously published C++ standards.


DR Applied to Behavior as published Correct behavior
P2602R2 C++20 there's machinery to prohibit certain removed such machinery
non-member size found by ADL

See also


ranges::ssize returns a signed integer equal to the size of a range
(C++20) (customization point object)
ranges::sized_range specifies that a range knows its size in constant time
(C++20) (concept)
ranges::distance returns the distance between an iterator and a sentinel, or
(C++20) between the beginning and end of a range
(niebloid)
size
ssize returns the size of a container or array
(C++17) (function template)
(C++20)

2024.06.10 http://cppreference.com