std::to_address (3) - Linux Manuals

std::to_address: std::to_address

NAME

std::to_address - std::to_address

Synopsis


Defined in header <memory>
template< class Ptr > (1) (since C++20)
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 pointee.
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>
  struct use_address : std::false_type { };


  template<class T>
      requires requires(const T& p) { std::pointer_traits<T>::to_address(p); }
  struct use_address<T> : std::true_type { };


  template<class T>
  constexpr T* to_address(T* p) noexcept
  {
      static_assert(!std::is_function_v<T>);
      return p;
  }


  template<class T>
  auto to_address(const T& p) noexcept
  {
      if constexpr (use_address<T>::value) {
          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.

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
                 (class template)
(C++11)


to_address obtains a raw pointer from a fancy pointer (inverse of pointer_to)
                 (public static member function of std::pointer_traits<Ptr>)
[static] (C++20)