Namespaces
Variants
Views
Actions

std::to_address

From cppreference.com
< cpp‎ | memory
Revision as of 03:52, 5 April 2019 by Glenfe (Talk | contribs)

 
 
Utilities library
General utilities
Relational operators (deprecated in C++20)
 
Dynamic memory management
Uninitialized memory algorithms
Constrained uninitialized memory algorithms
Allocators
Garbage collection support
(C++11)(until C++23)
(C++11)(until C++23)
(C++11)(until C++23)
(C++11)(until C++23)
(C++11)(until C++23)
(C++11)(until C++23)



 
Defined in header <memory>
template< class Ptr >
auto to_address(const Ptr& p) noexcept;
(1) (since C++20)
template< class T >
constexpr T* to_address(T* p) noexcept;
(2) (since C++20)

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.

Contents

Parameters

p - fancy or raw pointer

Return value

Raw pointer that represents the same address as p does.

Possible implementation

template<class, class = void>
struct use_address
    : false_type { };
 
template<class T>
struct use_address<T, void_t<decltype(pointer_traits<T>::to_address(declval<T>()))>>
    : true_type { };
 
template<class T>
constexpr T* to_address(T* p) noexcept
{
    static_assert(!is_function_v<T>);
    return p;
}
 
template<class T>
auto to_address(const T& p) noexcept
{
    if constexpr (use_address<T>::value) {
        return pointer_traits<T>::to_address(p);
    } else {
        return 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

#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

provides information about pointer-like types
(class template) [edit]
[static] (C++20)(optional)
obtains a raw pointer from a fancy pointer (inverse of pointer_to)
(public static member function of std::pointer_traits<Ptr>) [edit]