Title
basic_const_iterator's common_type specialization is underconstrained
Status
c++23
Section
[iterator.synopsis]
Submitter
Hewill Kang

Created on 2023-01-25.00:00:00 last changed 4 months ago

Messages

Date: 2023-02-13.11:31:32

Proposed resolution:

This wording is relative to N4928.

  1. Modify [iterator.synopsis], header <iterator> synopsis, as indicated:

    #include <compare>              // see [compare.syn]
    #include <concepts>             // see [concepts.syn]
    
    namespace std {
      […]
      template<class T, common_with<T> U>
        requires input_iterator<common_type_t<T, U>>
      struct common_type<basic_const_iterator<T>, U> {                                  // freestanding
        using type = basic_const_iterator<common_type_t<T, U>>;
      };
      template<class T, common_with<T> U>
        requires input_iterator<common_type_t<T, U>>
      struct common_type<U, basic_const_iterator<T>> {                                  // freestanding
        using type = basic_const_iterator<common_type_t<T, U>>;
      };
      template<class T, common_with<T> U>
        requires input_iterator<common_type_t<T, U>>
      struct common_type<basic_const_iterator<T>, basic_const_iterator<U>> {            // freestanding
        using type = basic_const_iterator<common_type_t<T, U>>;
      };
      […]
    }
    
Date: 2023-02-13.00:00:00

[ 2023-02-13 Approved at February 2023 meeting in Issaquah. Status changed: Immediate → WP. ]

Date: 2023-02-07.18:08:09

[ Issaquah 2023-02-07; LWG ]

Move to Immediate for C++23

Date: 2023-02-15.00:00:00

[ 2023-02-06; Jonathan provides improved wording based on Casey's suggestion during the prioritization poll. ]

Date: 2023-02-06.16:59:09

To make basic_const_iterator compatible with its unwrapped iterators, the standard defines the following common_type specialization:

template<class T, common_with<T> U>
struct common_type<basic_const_iterator<T>, U> {
  using type = basic_const_iterator<common_type_t<T, U>>;
};

For type U, when it shares a common type with the unwrapped type T of basic_const_iterator, the common type of both is basic_const_iterator of the common type of T and U.

However, since this specialization only constrains U and T to have a common type, this allows U to be any type that satisfies such requirement, such as optional<T>, in which case computing the common type of both would produce a hard error inside the specialization, because basic_const_iterator requires the template parameter to be input_iterator, while optional clearly isn't.

Previous resolution [SUPERSEDED]:

This wording is relative to N4928.

  1. Modify [iterator.synopsis], header <iterator> synopsis, as indicated:

    #include <compare>              // see [compare.syn]
    #include <concepts>             // see [concepts.syn]
    
    namespace std {
      […]
      template<class T, common_with<T> U>
        requires input_iterator<U>
      struct common_type<basic_const_iterator<T>, U> {                                  // freestanding
        using type = basic_const_iterator<common_type_t<T, U>>;
      };
      template<class T, common_with<T> U>
        requires input_iterator<U>
      struct common_type<U, basic_const_iterator<T>> {                                  // freestanding
        using type = basic_const_iterator<common_type_t<T, U>>;
      };
      […]
    }
    
History
Date User Action Args
2023-11-22 15:47:43adminsetstatus: wp -> c++23
2023-02-13 11:31:32adminsetmessages: + msg13394
2023-02-13 11:31:32adminsetstatus: immediate -> wp
2023-02-07 18:08:09adminsetmessages: + msg13287
2023-02-07 18:08:09adminsetstatus: new -> immediate
2023-02-06 16:59:09adminsetmessages: + msg13274
2023-01-28 13:24:36adminsetmessages: + msg13224
2023-01-25 00:00:00admincreate