[pointer.traits.types]

# 20 Memory management library [[mem]](./#mem)

## 20.2 Memory [[memory]](memory#pointer.traits.types)

### 20.2.3 Pointer traits [[pointer.traits]](pointer.traits#types)

#### 20.2.3.2 Member types [pointer.traits.types]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L770)

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*](#concept:has-elem-type "20.2.3.2 Member types [pointer.traits.types]") = // *exposition only*requires { typename *ptr-traits-elem*<Ptr>::type; }

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L792)

If Ptr satisfies [*has-elem-type*](#concept:has-elem-type "20.2.3.2 Member types [pointer.traits.types]"),
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]](pointer.traits.functions "20.2.3.3 Member functions");
otherwise, such a specialization has no members by any of those names[.](#2.sentence-1)

[ð](#lib:pointer,pointer_traits)

`using pointer = see below;
`

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L806)

*Type*: Ptr[.](#3.sentence-1)

[ð](#lib:element_type,pointer_traits)

`using element_type = see below;
`

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L816)

*Type*: typename *ptr-traits-elem*<Ptr>​::​type[.](#4.sentence-1)

[ð](#lib:difference_type,pointer_traits)

`using difference_type = see below;
`

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L826)

*Type*: Ptr​::​difference_type if
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Ptr​::​difference_type is valid and denotes a
type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwise,ptrdiff_t[.](#5.sentence-1)

[ð](#lib:rebind,pointer_traits)

`template<class U> using rebind = see below;
`

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L839)

*Alias template*: Ptr​::​rebind<U> if
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Ptr​::​rebind<U> is valid and denotes a
type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwise,SomePointer<U, Args> ifPtr is a class template instantiation of the form SomePointer<T, Args>,
where Args is zero or more type arguments; otherwise, the instantiation ofrebind is ill-formed[.](#6.sentence-1)
