std::addressof(3)

NAME
std::addressof - std::addressof

Synopsis
   Defined in header <memory>
   template< class T > (since C++11)
   T* addressof( T& arg ) noexcept; (until C++17)
   template< class T > (1) (since C++17)
   constexpr T* addressof( T& arg ) noexcept;
   template <class T> (2) (since C++17)
   const T* addressof( const T&& ) = delete;
   1) Obtains the actual address of the object or function arg, even in presence of
   overloaded operator&.
   2) Rvalue overload is deleted to prevent taking the address of const rvalues.
   The expression std::addressof(E) is a constant subexpression, if E is (since C++17)
   an lvalue constant subexpression.

Parameters
   arg - lvalue object or function

Return value
   Pointer to arg.

Possible implementation
   The implementation below is not constexpr (which requires compiler support).
   template<class T>
   typename std::enable_if<std::is_object<T>::value, T*>::type addressof(T& arg) noexcept
   {
       return reinterpret_cast<T*>(
                  &const_cast<char&>(
                      reinterpret_cast<const volatile char&>(arg)));
   }
   template<class T>
   typename std::enable_if<!std::is_object<T>::value, T*>::type addressof(T& arg) noexcept
   {
       return &arg;
   }
   Correct implementation of this function requires compiler support: GNU libstdc++,
   LLVM libc++, Microsoft STL

Notes
   Feature-test macro: __cpp_lib_addressof_constexpr

Example
   operator& may be overloaded for a pointer wrapper class to obtain a pointer to
   pointer: // Run this code
 #include <iostream>
 #include <memory>
 template<class T>
 struct Ptr {
     T* pad; // add pad to show difference between 'this' and 'data'
     T* data;
     Ptr(T* arg) : pad(nullptr), data(arg)
     {
         std::cout << "Ctor this = " << this << std::endl;
     }
     ~Ptr() { delete data; }
     T** operator&() { return &data; }
 };
 template<class T>
 void f(Ptr<T>* p)
 {
     std::cout << "Ptr overload called with p = " << p << '\n';
 }
 void f(int** p)
 {
     std::cout << "int** overload called with p = " << p << '\n';
 }
 int main()
 {
     Ptr<int> p(new int(42));
     f(&p); // calls int** overload
     f(std::addressof(p)); // calls Ptr<int>* overload, (= this)
 }

Possible output:
 Ctor this = 0x7fff59ae6e88
 int** overload called with p = 0x7fff59ae6e90
 Ptr overload called with p = 0x7fff59ae6e88

See also
   allocator the default allocator
              (class template)
   pointer_to obtains a dereferenceable pointer to its argument
   [static] (public static member function of std::pointer_traits<Ptr>)