std::to_address(3)

πŸ“¦ version 2024.07.05, in nixpkgs unstable, opensuse-leap 16.0

πŸ’– std::to_address(3) β€” C++ Standard Libary πŸ’–

okay bestie, welcome to the <memory>-core page for std::to_address ✨ it’s giving β€œget the address without forming a reference” and we’re gonna get into every single detail, no cap πŸ’…

🌸 NAME 🌸

std::to_address β€” std::to_address (yes literally, that’s the whole name πŸ˜­πŸ’…)

✨ Synopsis ✨

Defined in header <memory>

template< class Ptr >                               (1) (since C++20)
constexpr auto to_address( const Ptr& p ) noexcept;
template< class T >                                 (2) (since C++20)
constexpr T* to_address( T* p ) noexcept;

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 πŸ“

  • __cpp_lib_to_address β€” value 201711L, std (C++20), feature: 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 β€” provides information about pointer-like types; (C++11), class template.
  • to_address β€” obtains a raw pointer from a fancy pointer (inverse of pointer_to); [static], (C++20)(optional), public static member function of std::pointer_traits<Ptr>.

okay bye bestie πŸ’– this page is from http://cppreference.com, dated 2024.06.10, and it’s the std::to_address(3) manual β€” slay and stay pointer-safe ✨🫢

πŸ“¦ where this page comes from