additional constraints upon calling std::ranges::get<I>:
- std::tuple_element<I, std::remove_cv_t<Tup>> or std::tuple_element_t<I, std::remove_cvref_t<Tup>> must be a well-formed type.
- std::tuple_size<std::remove_cv_t<Tup>> or std::tuple_size<std::remove_cvref_t<T>> must also be a well-formed type.
- I < std::tuple_size_v<std::remove_cvref_t<Tup>> must be true.

On Tue, Oct 26, 2021 at 10:08 AM Desmond Gold Bongcawel <> wrote:
get has been defined as a function template in std::ranges for std::ranges::subrange to obtain the pair of iterator and sentinel for structured binding support. (if necessary)

My suggestion is that "get" for std::ranges::subrange should be defined in namespace std for the CPO purposes of std::ranges::get or may be defined as a member function template.

std::ranges::get will be redefined its name as a customization point object.

From the following definition, get is defined as a variable template where the non-type template parameter I denotes the index of the tuple-like object.
inline namespace /* unspecified */ {
  template <size_t I>
  inline constexpr /* unspecified */ get = /* unspecified */; 

A call to std::ranges::get 
1. is expression-equivalent to "return get<I>(std::forward<Tup>(tup))"
    - where any declarations of get with appropriate template arguments can be found in ADL.
2. otherwise, is expression-equivalent to "return std::forward<Tup>(tup).template get<I>()"
    - where get is a member function template with appropriate template arguments.
3. otherwise, if the type is equal to an array type, then it is expression-equivalent to "return tup[i]"

The potential benefits of std::ranges::get are to be encouraged used for functions that use std::get for tuple-like to support user-defined types such as std::apply in which internally used std::get where it prevents from passing a user-defined type that has no std::get overload.