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'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 |