Proposed resolution:
This wording is relative to N4917.
Modify [pointer.traits.general] as indicated:
-1- The class template pointer_traits supplies a uniform interface to certain attributes of pointer-like types.
namespace std { template<class Ptr> struct pointer_traits {using pointer = Ptr;using element_type = see below;using difference_type = see below;template<class U> using rebind = see below;static pointer pointer_to(see below r);see below; }; template<class T> struct pointer_traits<T*> { using pointer = T*; using element_type = T; using difference_type = ptrdiff_t; template<class U> using rebind = U*; static constexpr pointer pointer_to(see below r) noexcept; }; }
Modify [pointer.traits.types] as indicated:
-?- The definitions in this subclause make use of the following exposition-only class template and concept:
template<class T> struct ptr-traits-elem // exposition only { }; template<class T> requires requires { typename T::element_type; } struct ptr-traits-elem<T> { using type = typename T::element_type; }; template<template<class...> class SomePointer, class T, class... Args> requires (!requires { typename SomePointer<T, Args...>::element_type; }) struct ptr-traits-elem<SomePointer<T, Args...>> { using type = T; }; template<class Ptr> concept has-elem-type = // exposition only requires { typename ptr-traits-elem<Ptr>::type; }-?- If Ptr satisfies has-elem-type, a specialization pointer_traits<Ptr> generated from the pointer_traits primary template has the following members as well as those described in [pointer.traits.functions]; otherwise, such a specialization has no members by any of those names.
using pointer = see below;-?- Type: Ptr.
using element_type = see below;-1- Type: typename ptr-traits-elem<Ptr>::type.
Ptr::element_type if the qualified-id Ptr::element_type is valid and denotes a type ([temp.deduct]); otherwise, T if Ptr is a class template instantiation of the form SomePointer<T, Args>, where Args is zero or more type arguments; otherwise, the specialization is ill-formed.using difference_type = see below;-2- Type: Ptr::difference_type if the qualified-id Ptr::difference_type is valid and denotes a type ([temp.deduct]); otherwise, ptrdiff_t.
template<class U> using rebind = see below;-3- Alias template: Ptr::rebind<U> if the qualified-id Ptr::rebind<U> is valid and denotes a type ([temp.deduct]); otherwise, SomePointer<U, Args> if Ptr is a class template instantiation of the form SomePointer<T, Args>, where Args is zero or more type arguments; otherwise, the instantiation of rebind is ill-formed.
Modify [pointer.traits.optmem] as indicated:
-1- Specializations of pointer_traits may define the member declared in this subclause to customize the behavior of the standard library. A specialization generated from the pointer_traits primary template has no member by this name.
static element_type* to_address(pointer p) noexcept;-1- Returns: A pointer of type element_type* that references the same location as the argument p.