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

### 2951. `iterator_traits` should SFINAE for `void*` and function pointers

Section: 25.3.2.3 [iterator.traits] Status: Resolved Submitter: Billy Robert O'Neal III Opened: 2017-03-24 Last modified: 2020-09-06

Priority: 3

View all other issues in [iterator.traits].

View all issues with Resolved status.

Discussion:

A customer recently triggered an unexpected SFINAE condition with class `path`. We constrain the constructor that takes `const Source&` by asking if `iterator_traits<Source>::value_type` is one that's OK. This forms `iterator_traits<void*>`, which is a hard error, as it tries to form `void&`.

Pointers-to-non-object-type can never act as iterators, as they don't support pointer arithmetic (as we recently discovered in `atomic<void*>` / `atomic<int(*)(int)>`).

[2017-07 Toronto Wed Issue Prioritization]

Priority 3; Billy to look into arrays of unknown bounds

[2019-02; Kona Wednesday night issue processing]

This was resolved by the adoption of P0896 in San Diego.

Proposed resolution:

This wording is relative to N4659.

1. Change 25.3.2.3 [iterator.traits] as indicated:

   > -3- It is specialized for pointers as

   > >     namespace std {
   > >       template<class T> struct iterator_traits<T*> {
   > >         using difference_type = ptrdiff_t;
   > >         using value_type = T;
   > >         using pointer = T*;
   > >         using reference = T&;
   > >         using iterator_category = random_access_iterator_tag;
   > >       };
   > >     }

   > and for pointers to `const` as

   > >     namespace std {
   > >       template<class T> struct iterator_traits<const T*> {
   > >         using difference_type = ptrdiff_t;
   > >         using value_type = T;
   > >         using pointer = const T*;
   > >         using reference = const T&;
   > >         using iterator_category = random_access_iterator_tag;
   > >       };
   > >     }

   > -?- These partial specializations for pointers apply only when `T` is an object type.