basic_const_iterator
's common_type
specialization is underconstrainedSection: 24.2 [iterator.synopsis] Status: C++23 Submitter: Hewill Kang Opened: 2023-01-25 Last modified: 2023-11-22
Priority: Not Prioritized
View all other issues in [iterator.synopsis].
View all issues with C++23 status.
Discussion:
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
.
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.
Modify 24.2 [iterator.synopsis], header
<iterator>
synopsis, as indicated:#include <compare> // see 17.11.1 [compare.syn] #include <concepts> // see 18.3 [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>>; }; […] }
[2023-02-06; Jonathan provides improved wording based on Casey's suggestion during the prioritization poll.]
[Issaquah 2023-02-07; LWG]
Move to Immediate for C++23
[2023-02-13 Approved at February 2023 meeting in Issaquah. Status changed: Immediate → WP.]
Proposed resolution:
This wording is relative to N4928.
Modify 24.2 [iterator.synopsis], header <iterator>
synopsis, as indicated:
#include <compare> // see 17.11.1 [compare.syn] #include <concepts> // see 18.3 [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>>; }; […] }