table of contents
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 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 Feature
__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 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>)
2024.06.10 | http://cppreference.com |