herwise. 

A call to ` ranges::cend ` is [ expression-equivalent ](/w/cpp/language/expressions#Expression-equivalence "cpp/language/expressions") to  [ ranges::  end  ](http://en.cppreference.com/w/cpp/ranges-ranges-placeholder/end) (  static_cast  < CT  && > (  t  )  )  .  |  (until C++23)   
---|---  
If the argument is an lvalue or  [ ranges::  enable_borrowed_range
](http://en.cppreference.com/w/cpp/ranges/borrowed_range) < [ std::
remove_cv_t  ](http://en.cppreference.com/w/cpp/types/remove_cv) < T  >> is
true  , then a call to ` ranges::cend ` is [ expression-equivalent
](/w/cpp/language/expressions#Expression-equivalence
"cpp/language/expressions") to:

  * [ std::  const_sentinel  ](http://en.cppreference.com/w/cpp/iterator/const_sentinel) < decltype  (  U  )  > (  U  )  for some expression ` U ` equivalent to  [ ranges::  end  ](http://en.cppreference.com/w/cpp/ranges-ranges-placeholder/end) (  /*possibly-const-range*/  (  t  )  )  . 

In all other cases, a call to ` ranges::cend ` is ill-formed, which can result in [ substitution failure ](/w/cpp/language/sfinae "cpp/language/sfinae") when the call appears in the immediate context of a template instantiation.  |  (since C++23)   
  
If  [ ranges::  cend  ](http://en.cppreference.com/w/cpp/ranges-ranges-
placeholder/cend) (  e  )  is valid for an expression  e  , where  decltype  (
(  e  )  )  is ` T ` , then  ` CT ` models  [ std::ranges::range
](/w/cpp/ranges/range "cpp/ranges/range") , and  (until C++23)  [ std::
sentinel_for  ](http://en.cppreference.com/w/cpp/iterator/sentinel_for) < S, I
> is  true  in all cases, where ` S ` is  decltype  (  [ ranges::  cend
](http://en.cppreference.com/w/cpp/ranges-ranges-placeholder/cend) (  e  )  )
, and ` I ` is  decltype  (  [ ranges::  cbegin
](http://en.cppreference.com/w/cpp/ranges-ranges-placeholder/cbegin) (  e  )
)  .  Additionally, ` S ` models [ ` _constant-iterator_ `
](/w/cpp/ranges/constant_range "cpp/ranges/constant range") if it models [ `
input_iterator ` ](/w/cpp/iterator/input_iterator "cpp/iterator/input
iterator") .  (since C++23)

###  Customization point objects

The name ` ranges::cend ` 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 ` ___cend_fn_ ` .

All instances of ` ___cend_fn_ ` are equal. The effects of invoking different
instances of type ` ___cend_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::cend ` 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::cend ` above, ` ___cend_fn_ `
models  

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

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

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

Run this code

    
    
    #include <algorithm>
    #include <cassert>
    #include <ranges>
    #include <vector>
     
    int main()
    {