This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++23 status.
iterator_traits<common_iterator>::pointer
should conform to §[iterator.traits]Section: 24.5.5.2 [common.iter.types] Status: C++23 Submitter: Casey Carter Opened: 2022-01-20 Last modified: 2023-11-22
Priority: Not Prioritized
View all issues with C++23 status.
Discussion:
24.3.2.3 [iterator.traits]/1 says:
[…] In addition, the types
iterator_traits<I>::pointer iterator_traits<I>::referenceshall be defined as the iterator's pointer and reference types; that is, for an iterator object
a
of class type, the same type asdecltype(a.operator->())
anddecltype(*a)
, respectively. The typeiterator_traits<I>::pointer
shall bevoid
for an iterator of class typeI
that does not supportoperator->
. […]
24.5.5.2 [common.iter.types]/1 slightly contradicts this:
The nested typedef-names of the specialization of
iterator_traits
forcommon_iterator<I, S>
are defined as follows.
[…]
(1.3) — If the expression
a.operator->()
is well-formed, wherea
is an lvalue of typeconst common_iterator<I, S>
, thenpointer
denotes the type of that expression. Otherwise,pointer
denotesvoid
.
"The type of a.operator->()
" is not necessarily the same as decltype(a.operator->())
:
when the expression is an lvalue or xvalue of type T
, "the type of a.operator->()
" is T
but decltype(a.operator->())
is either T&
or T&&
. An implementation
therefore cannot conform to the requirements of both cited paragraphs for some specializations of common_iterator
.
a.operator->()
" was not cognizant of the difference in meaning and intended to actually write
decltype(a.operator->())
.
[2022-01-30; Reflector poll]
Set status to Tentatively Ready after five votes in favour during reflector poll.
[2022-02-10 Approved at February 2022 virtual plenary. Status changed: Tentatively Ready → WP.]
Proposed resolution:
This wording is relative to N4901.
[Drafting Note: The wording change below includes an additional drive-by fix that ensures that the last sentence "Otherwise,
pointer
denotesvoid
" cannot be misinterpreted (due to the leading "If") to apply also for a situation when the outcome of the expressiona.operator->()
for a non-const
common_iterator<I, S>
is reflected upon.]
Modify 24.5.5.2 [common.iter.types] as indicated:
-1- The nested typedef-names of the specialization of
iterator_traits
forcommon_iterator<I, S>
are defined as follows.
[…]
(1.3) — Let
a
denote an lvalue of typeconst common_iterator<I, S>
. If the expressiona.operator->()
is well-formed,wherethena
is an lvalue of typeconst common_iterator<I, S>
,pointer
denotesdecltype(a.operator->())
the type of that expression. Otherwise,pointer
denotesvoid
.