24 Ranges library [ranges]

24.3 Range access [range.access]

24.3.9 ranges​::​size [range.prim.size]

The name size denotes a customization point object.
The expression ranges​::​size(E) for some subexpression E with type T is expression-equivalent to:
  • decay-copy(extent_­v<T>) if T is an array type ([basic.compound]).
  • Otherwise, if disable_­sized_­range<remove_­cv_­t<T>> ([range.sized]) is false:
    • decay-copy(E.size()) if it is a valid expression and its type I is integer-like ([iterator.concept.winc]).
    • Otherwise, decay-copy(size(E)) if it is a valid expression and its type I is integer-like with overload resolution performed in a context that includes the declaration:
      template<class T> void size(T&&) = delete;
          
      and does not include a declaration of ranges​::​size.
  • Otherwise, make-unsigned-like(ranges​::​end(E) - ranges​::​begin(E)) ([range.subrange]) if it is a valid expression and the types I and S of ranges​::​begin(E) and ranges​::​end(E) (respectively) model both sized_­sentinel_­for<S, I> ([iterator.concept.sizedsentinel]) and forward_­iterator<I>. However, E is evaluated only once.
  • Otherwise, ranges​::​size(E) is ill-formed.
    Note
    : This case can result in substitution failure when ranges​::​size(E) appears in the immediate context of a template instantiation. — end note
     ]
Note
:
Whenever ranges​::​size(E) is a valid expression, its type is integer-like.
— end note
 ]