# std::pointer_traits

From cppreference.com
< cpp‎ | memory

Defined in header `<memory>` |  |
template< class Ptr > struct pointer_traits; | (1) | (since C++11)
template< class T > struct pointer_traits<T*>; | (2) | (since C++11)

The `pointer_traits` class template provides the standardized way to access certain properties of pointer-like types (fancy pointers, such as boost::interprocess::offset_ptr). The standard template std::allocator_traits relies on `pointer_traits` to determine the defaults for various typedefs required by Allocator.

1) The non-specialized `pointer_traits` declares the following types:

### Member types

Type | Definition
`pointer` | Ptr
`element_type` | Ptr::element_type if present. Otherwise `T` if `Ptr` is a template instantiation Template<T, Args...>
`difference_type` | Ptr::difference_type if present, otherwise std::ptrdiff_t

### Member alias templates

Template | Definition
template <class U> using rebind | Ptr::rebind<U> if exists, otherwise Template<U, Args...> if `Ptr` is a template instantiation Template<T, Args...>

### Member functions

pointer_to [static] | obtains a dereferenceable pointer to its argument (public static member function)

2) A specialization is provided for pointer types, `T*`, which declares the following types

### Member types

Type | Definition
`pointer` | T*
`element_type` | T
`difference_type` | std::ptrdiff_t

### Member alias templates

Template | Definition
template< class U > using rebind | U*

### Member functions

pointer_to [static] | obtains a dereferenceable pointer to its argument (public static member function)

3) A specialization for user-defined fancy pointer types may define an additional static member function

### Optional Member functions

to_address [static] (C++20) | obtains a raw pointer from a fancy pointer (inverse of pointer_to) (public static member function)

### Notes

The rebind member template alias makes it possible, given a pointer-like type that points to T, to obtain the same pointer-like type that points to U. For example,

    using another_pointer = std::pointer_traits<std::shared_ptr<int>>::rebind<double>;
    static_assert(std::is_same<another_pointer, std::shared_ptr<double>>::value);

### Example

Run this code

    #include <memory>
    #include <iostream>

    template <class Ptr>
    struct BlockList
    {
       // Predefine a memory block
       struct block;

       // Define a pointer to a memory block from the kind of pointer Ptr s
       // If Ptr is any kind of T*, block_ptr_t is block*
       // If Ptr is smart_ptr<T>, block_ptr_t is smart_ptr<block>
       using block_ptr_t = typename std::pointer_traits<Ptr>::template rebind<block>;

       struct block
       {
          std::size_t size;
          block_ptr_t next_block;
       };

       block_ptr_t free_blocks;
    };

    int main()
    {
        BlockList<int*> bl1;
        // The type of bl1.free_blocks is block*

        BlockList<std::shared_ptr<char>> bl2;
        // The type of bl2.free_blocks is std::shared_ptr<block>
        std::cout << bl2.free_blocks.use_count() << '\n';
    }

Output:

    ​0​

### See also

allocator_traits (C++11) | provides information about allocator types (class template)
addressof (C++11) | obtains actual address of an object, even if the & operator is overloaded (function template)

Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/memory/pointer_traits&oldid=107918"