ecltype  (  [ ranges::  size  ](http://en.cppreference.com/w/cpp/ranges/size) (  t  )  )  , if it is wider than  [ std::ptrdiff_t ](/w/cpp/types/ptrdiff_t "cpp/types/ptrdiff t") , or 
  * [ std::ptrdiff_t ](/w/cpp/types/ptrdiff_t "cpp/types/ptrdiff t") otherwise. 

If  [ ranges::  size  ](http://en.cppreference.com/w/cpp/ranges/size) (  t  )
is ill-formed, a call to ` ranges::ssize ` is also ill-formed, which can
result in [ substitution failure ](/w/cpp/language/sfinae
"cpp/language/sfinae") when  ranges  ::  ssize  (  t  )  appears in the
immediate context of a template instantiation.

##  Contents

  * 1  Customization point objects 
  * 2  Notes 
  * 3  Example 
  * 4  Defect reports 
  * 5  See also 

  
---  
  
###  Customization point objects

The name ` ranges::ssize ` denotes a _customization point object_ , which is a
const [ function object ](/w/cpp/named_req/FunctionObject "cpp/named
req/FunctionObject") of a [ literal ](/w/cpp/named_req/LiteralType "cpp/named
req/LiteralType") [ ` semiregular ` ](/w/cpp/concepts/semiregular
"cpp/concepts/semiregular") class type. For exposition purposes, the cv-
unqualified version of its type is denoted as ` ___ssize_fn_ ` .

All instances of ` ___ssize_fn_ ` are equal. The effects of invoking different
instances of type ` ___ssize_fn_ ` on the same arguments are equivalent,
regardless of whether the expression denoting the instance is an lvalue or
rvalue, and is const-qualified or not (however, a volatile-qualified instance
is not required to be invocable). Thus, ` ranges::ssize ` can be copied freely
and its copies can be used interchangeably.

Given a set of types ` Args... ` , if  [ std::  declval
](http://en.cppreference.com/w/cpp/utility/declval) < Args  > (  )  ...  meet
the requirements for arguments to ` ranges::ssize ` above, ` ___ssize_fn_ `
models  

  * [ std::  invocable  ](http://en.cppreference.com/w/cpp/concepts/invocable) < __ssize_fn, Args...  > , 
  * [ std::  invocable  ](http://en.cppreference.com/w/cpp/concepts/invocable) < const  __ssize_fn, Args...  > , 
  * [ std::  invocable  ](http://en.cppreference.com/w/cpp/concepts/invocable) < __ssize_fn  & , Args...  > , and 
  * [ std::  invocable  ](http://en.cppreference.com/w/cpp/concepts/invocable) < const  __ssize_fn  & , Args...  > .   

Otherwise, no function call operator of ` ___ssize_fn_ ` participates in
overload resolution.

###  [ [ edit ](/mwiki/index.php?title=cpp/ranges/ssize&action=edit&section=1
"Edit section: Notes") ]  Notes

If  ranges  ::  ssize  (  e  )  is valid for an expression  e  , the return
type is a [ signed-integer-like
](/w/cpp/iterator/weakly_incrementable#Integer-like_types "cpp/iterator/weakly
incrementable") type, i.e. an integer type for which  [ std::is_signed_v
](/w/cpp/types/is_signed "cpp/types/is signed") is  true  , or a signed-
integer-class type.

The width of integer-like types can be detected by  [
std::numeric_limits::digits ](/w/cpp/types/numeric_limits/digits
"cpp/types/numeric limits/digits") .

###  [ [ edit ](/mwiki/index.php?title=cpp/ranges/ssize&action=edit&section=2
"Edit section: Example") ]  Example

Run this code

    
    
    #include <array>
    #include <iostream>
    #include <ranges>
    #include <type_traits>
     
    int main()
    {
        [std::array](http://en.cppreference.com/w/cpp/container/array) arr{1, 2, 3, 4, 5};
        auto s = std::ranges::ssize(arr);
     
        [std::cout](http://en.cppreference.com/w/cpp/io/cout) << "ranges::ssize(arr) = " << s << '\n'
                  << "ranges::ssize is "
                  << ([std::is_signed_v](http://en.cppreference.com/w/cpp/types/is_signed)<decltype(s)> ? "signed" : "unsigned")
                  << '\n';
     
        [std::cout](http://en.cppreference.com/w/cpp/io/cout) << "reversed arr: ";
     
        for (--s; s >= 0; --s)
            [std::cout](http://en.cppreference.com/w/cpp/io/cout) << arr[s] << ' ';
     
        [std::cout](http://en.cppreference.com/w/cpp/io/cout) << "\n"