Document Number: P0653r1
Project: Programming Language C++
Audience: Library Evolution Working Group
Author: Glen Joseph Fernandes (email@example.com)
This paper proposes adding a new function
to_address to obtain
a raw pointer from an object of a pointer-like type, and an optional
customization point in class template
pointer_traits via a member
function of the same name.
Provide a free function that uses a
function only if it exists. This preserves compatibility for any user
pointer_traits that do not define a
to_address member function.
It is often necessary to obtain a raw pointer from an object of any
pointer-like type. One common use is writing allocator-aware code where an
pointer member type is not a raw pointer type.
Typically the expression
addressof(*p) is used but this is not
p does not reference storage that has an object
constructed in it. This means that using this expression to obtain a raw
pointer for the purpose of constructing an object (e.g. via a placement
new-expression or via an allocator) is incorrect.
A common example of such code:
auto p = a.allocate(1);
std::allocator_traits<A>::construct(a, std::addressof(*p), v);
The correct code now looks like:
auto p = a.allocate(1);
std::allocator_traits<A>::construct(a, std::to_address(p), v);
To customize the behavior of this function for a pointer-like type, users
pointer_traits for that type and define member
Typically implementors work around this problem by defining a utility like the following:
template <class Ptr>
auto to_address(const Ptr& p) noexcept
template <class T>
T* to_address(T* p) noexcept
This proposal provides a standard library solution, with an optional customization point.
The C++ standard library already provides
for supporting pointer-like types and this
to_address is the
natural inverse of its
pointer_to member function.
The Boost C++ library collection now
contains an implementation of an earlier revision of this proposal in the Core
boost::pointer_traits implementation is used by
several Boost libraries, starting with the 1.65 release.
All changes are relative to N4640.
1. Insert into 20.10.2 [memory.syn] as follows:
// 20.10.3, pointer traits
template <class Ptr> struct pointer_traits;
template <class T> struct pointer_traits<T*>;
2. Insert after 20.10.3 [pointer.traits] as follows:
2. Add to 220.127.116.11 [pointer.traits.functions] as follows:
Peter Dimov, Jonathan Wakely, and Howard Hinnant helped shape the revised proposal. Peter Dimov suggested the better design as well as reviewed the implementation and tests of the Boost version. Jonathan Wakely pointed out the issue that motivated this proposal. Michael Spencer and Joel Falcou reviewed this paper.