Scroll to navigation

std::to_address(3) C++ Standard Libary std::to_address(3)

NAME

std::to_address - std::to_address

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's no valid object for the parameter of std::addressof to bind to.


The fancy pointer overload of 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.


Feature-test macro: __cpp_lib_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)
obtains a raw pointer from a fancy pointer (inverse of
to_address pointer_to)
[static] (C++20)(optional) (public static member function of
std::pointer_traits<Ptr>)

2022.07.31 http://cppreference.com