< cpp‎ | iterator
Iterator library
Iterator concepts
Iterator primitives
Algorithm concepts and utilities
Indirect callable concepts
Common algorithm requirements
Iterator adaptors
Stream iterators
Iterator customization points
Iterator operations
Range access
Defined in header <iterator>
Call signature
template< std::input_or_output_iterator I, std::sentinel_for<I> S >
constexpr std::iter_difference_t<I> distance( I first, S last );
(1) (since C++20)
template< ranges::range R>
constexpr ranges::range_difference_t<R> distance(R&& r);
(2) (since C++20)
1) Returns the number of hops from first to last.
2) Same as (1), but uses r as the source range, using ranges::size(r) if R models ranges::sized_range; otherwise as if using ranges::begin(r) as first and ranges::end(r) as last.

The function-like entities described on this page are niebloids, that is:

In practice, they may be implemented as function objects, or with special compiler extensions.


[edit] Parameters

first - iterator pointing to the first element
last - sentinel denoting the end of the range first is an iterator to
r - range to calculate the distance of

[edit] Return value

The number of increments needed to go from first to last. The value may be negative if I and S model std::same_as<S, I> && std::sized_sentinel_for<S, I> are used and first is reachable from last.

[edit] Complexity

1) If S models std::sized_sentinel_for<S, I>, complexity is constant; otherwise linear.
2) If R models ranges::sized_range, complexity is constant; otherwise same as (1).

[edit] Possible implementation

struct distance_fn {
  template<std::input_or_output_iterator I, std::sentinel_for<I> S>
  constexpr std::iter_difference_t<I> operator()(I first, S last) const
    if constexpr (std::sized_sentinel_for<S, I>) {
        return last - first;
    else {
        std::iter_difference_t<I> result = 0;
        while (first != last) {
        return result;
  template<ranges::range R>
  constexpr ranges::range_difference_t<R> operator()(R&& r) const
    if constexpr (ranges::sized_range<std::remove_cvref_t<R>>) {
      return static_cast<ranges::range_difference_t<R>>(ranges::size(r));
    else {
      return ranges::distance(ranges::begin(r), ranges::end(r));
inline constexpr auto distance = distance_fn{};

[edit] Example

#include <iostream>
#include <iterator>
#include <vector>
int main() 
    std::vector<int> v{ 3, 1, 4 };
    namespace ranges = std::ranges;
    std::cout << "distance(first, last) = "
              << ranges::distance(v.begin(), v.end()) << '\n'
              << "distance(last, first) = "
              << ranges::distance(v.end(), v.begin()) << '\n'
              << "distance(v) = " << ranges::distance(v) << '\n';


distance(first, last) = 3
distance(last, first) = -3
distance(v) = 3

[edit] See also

advances an iterator by given distance or to a given bound
(niebloid) [edit]
returns the number of elements satisfying specific criteria
(niebloid) [edit]
returns the distance between two iterators
(function template) [edit]