This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of LEWG status.

### 3454. `pointer_traits::pointer_to` should be `constexpr`

Section: 20.2.3 [pointer.traits] Status: LEWG Submitter: Alisdair Meredith Opened: 2020-06-21 Last modified: 2022-07-21

Priority: Not Prioritized

View all other issues in [pointer.traits].

View all issues with LEWG status.

Discussion:

Trying to implement a `constexpr std::list` (inspired by Tim Song's note on using variant members in the node) as part of evaluating the `constexpr` container and adapters proposals, I hit problems I could not code around in `pointer_traits`, as only the specialization for native pointers has a `constexpr pointer_to` function.

This means that containers of my custom allocator, that delegates all allocation behavior to `std::allocator<T>` but adds extra telemetry and uses a fancy pointer, does not work with the approach I tried for implementing `list` (common link type, shared between nodes, and stored as `end` sentinel directly in the `list` object).

[2020-07-17; Forwarded to LEWG after review in telecon]

[2022-07-19; Casey Carter comments]

This is no longer simply a theoretical problem that impedes implementing `constexpr std::list`, but an actual defect affecting current implementations of `constexpr std::string`. More specifically, it makes it impossible to support so-called "fancy pointers" in a `constexpr basic_string` that performs the small string optimization (SSO). (`pointer_traits::pointer_to` is critically necessary to get a pointer that designates the SSO buffer.) As things currently stand, `constexpr basic_string` can support fancy pointers or SSO, but not both.

Proposed resolution:

This wording is relative to N4861.

1. Modify 20.2.3 [pointer.traits] as indicated:

   > -1- The class template `pointer_traits` supplies a uniform interface to certain attributes of pointer-like types.

   > >     namespace std {
   > >       template<class Ptr> struct pointer_traits {
   > >         using pointer         = Ptr;
   > >         using element_type    = see below;
   > >         using difference_type = see below;

   > >         template<class U> using rebind = see below;

   > >         static constexpr pointer pointer_to(see below r);
   > >       };
   > >       […]
   > >     }

2. Modify 20.2.3.3 [pointer.traits.functions] as indicated:

   >     static constexpr pointer pointer_traits::pointer_to(see below r);
   >     static constexpr pointer pointer_traits<T*>::pointer_to(see below r) noexcept;

   > > -1- Mandates: For the first member function, `Ptr::pointer_to(r)` is well-formed.

   > > -2- Preconditions: For the first member function, `Ptr::pointer_to(r)` returns a pointer to `r` through which indirection is valid.

   > > -3- Returns: The first member function returns `Ptr::pointer_to(r)`. The second member function returns `addressof(r)`.

   > > -4- Remarks: If `element_type` is cv `void`, the type of `r` is unspecified; otherwise, it is `element_type&`.