# std::to_address

From cppreference.com
< cpp‎ | memory

Defined in header `<memory>` |  |
template< class Ptr > constexpr auto to_address( const Ptr& p ) noexcept; | (1) | (since C++20)
template< class T > constexpr T* to_address( T* p ) noexcept; | (2) | (since C++20)

Obtain the address represented by p without forming a reference to the object pointed to by p.

1) Fancy pointer overload: If the expression std::pointer_traits<Ptr>::to_address(p) is well-formed, returns the result of that expression. Otherwise, returns std::to_address(p.operator->()).
2) Raw pointer overload: If `T` is a function type, the program is ill-formed. Otherwise, returns p unmodified.

### Parameters

p | - | fancy or raw pointer

### Return value

Raw pointer that represents the same address as p does.

### Possible implementation

    template<class T>
    constexpr T* to_address(T* p) noexcept
    {
        static_assert(!std::is_function_v<T>);
        return p;
    }

    template<class T>
    constexpr auto to_address(const T& p) noexcept
    {
        if constexpr (requires{ std::pointer_traits<T>::to_address(p); })
            return std::pointer_traits<T>::to_address(p);
        else
            return std::to_address(p.operator->());
    }

### Notes

`std::to_address` can be used even when p does not reference storage that has an object constructed in it, in which case std::addressof(*p) cannot be used because there is no valid object for the parameter of std::addressof to bind to.

The fancy pointer overload of `std::to_address` inspects the std::pointer_traits<Ptr> specialization. If instantiating that specialization is itself ill-formed (typically because `element_type` cannot be defined), that results in a hard error outside the immediate context and renders the program ill-formed.

`std::to_address` may additionally be used on iterators that satisfy std::contiguous_iterator.

Feature-test macro | Value | Std | Comment
--- | --- | --- | ---
`__cpp_lib_to_address` | 201711L | (C++20) | Utility to convert a pointer to a raw pointer (`std::to_address`)

### Example

Run this code

    #include <memory>

    template<class A>
    auto allocator_new(A& a)
    {
        auto p = a.allocate(1);
        try
        {
            std::allocator_traits<A>::construct(a, std::to_address(p));
        }
        catch (...)
        {
            a.deallocate(p, 1);
            throw;
        }
        return p;
    }

    template<class A>
    void allocator_delete(A& a, typename std::allocator_traits<A>::pointer p)
    {
        std::allocator_traits<A>::destroy(a, std::to_address(p));
        a.deallocate(p, 1);
    }

    int main()
    {
        std::allocator<int> a;
        auto p = allocator_new(a);
        allocator_delete(a, p);
    }

### See also

pointer_traits (C++11) | provides information about pointer-like types (class template)
to_address [static] (C++20)(optional) | obtains a raw pointer from a fancy pointer (inverse of `pointer_to`) (public static member function of `std::pointer_traits<Ptr>`)

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