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.


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
    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);
        return std::to_address(p.operator->());


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)


#include <memory>
template<class A>
auto allocator_new(A& a)
    auto p = a.allocate(1);
        std::allocator_traits<A>::construct(a, std::to_address(p));
    catch (...)
        a.deallocate(p, 1);
    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

provides information about pointer-like types
(class template)
[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>)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.