From cppreference.com
Defined in header
template<classT>T*addressof(T&arg)noexcept; (1) (since C++11)
(constexpr since C++17)template<classT>constT*addressof(constT&&)=delete; (2) (since C++11)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
, if e is an lvalue constant subexpression.
(since C++17)Parameters
arg - lvalue object or function Return value
Pointer to arg.
Possible implementation
The implementation below is not constexpr, because reinterpret_cast is not usable in a constant expression. Compiler support is needed (see below).
template<classT>typenamestd::enable_if<std::is_object<T>::value,T*>::typeaddressof(T&arg)noexcept{returnreinterpret_cast<T*>(&const_cast<char&>(reinterpret_cast<constvolatilechar&>(arg)));}template<classT>typenamestd::enable_if<!std::is_object<T>::value,T*>::typeaddressof(T&arg)noexcept{return&arg;}Correct implementation of this function requires compiler support:
,
,
.
Notes
macroValueStdFeature
(C++17)constexprstd::addressofconstexpr for addressof is added by
, and MSVC STL applies the change to C++14 mode as a defect report.
There are some weird cases where use of built-in operator& is ill-formed due to
even if it is not overloaded, and std::addressof can be used instead.
template<classT>structholder{Tt;};structincomp;intmain(){holder<holder<incomp>*>x{};// &x; // error: argument-dependent lookup attempts to instantiate holder<incomp>std::addressof(x);// OK}Example
operator& may be overloaded for a pointer wrapper class to obtain a pointer to pointer:
Run this code
#include<iostream>#include<memory>template<classT>structPtr{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<<'\n';}~Ptr(){deletedata;}T**operator&(){return&data;}};template<classT>voidf(Ptr<T>*p){std::cout<<"Ptr overload called with p = "<<p<<'\n';}voidf(int**p){std::cout<<"int** overload called with p = "<<p<<'\n';}intmain(){Ptr<int>p(newint(42));f(&p);// calls int** overloadf(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 Defect reports
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR Applied to Behavior as published Correct behavior
C++11 std::addressof<constT> could take address of rvalues disallowed by a deleted overload See also
the default allocator
(class template)
[static]
obtains a dereferenceable pointer to its argument
(public static member function of std::pointer_traits<Ptr>)