Title
iterator_traits<common_iterator>::pointer should conform to §[iterator.traits]
Status
c++23
Section
[common.iter.types]
Submitter
Casey Carter

Created on 2022-01-20.00:00:00 last changed 4 months ago

Messages

Date: 2022-02-10.12:58:57

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 denotes void" cannot be misinterpreted (due to the leading "If") to apply also for a situation when the outcome of the expression a.operator->() for a non-const common_iterator<I, S> is reflected upon.]

  1. Modify [common.iter.types] as indicated:

    -1- The nested typedef-names of the specialization of iterator_traits for common_iterator<I, S> are defined as follows.

    1. […]

    2. (1.3) — Let a denote an lvalue of type const common_iterator<I, S>. If the expression a.operator->() is well-formed, where a is an lvalue of type const common_iterator<I, S>, then pointer denotes decltype(a.operator->())the type of that expression. Otherwise, pointer denotes void.

Date: 2022-02-10.00:00:00

[ 2022-02-10 Approved at February 2022 virtual plenary. Status changed: Tentatively Ready → WP. ]

Date: 2022-01-15.00:00:00

[ 2022-01-30; Reflector poll ]

Set status to Tentatively Ready after five votes in favour during reflector poll.

Date: 2022-01-20.00:00:00

[iterator.traits]/1 says:

[…] In addition, the types

iterator_traits<I>::pointer
iterator_traits<I>::reference

shall be defined as the iterator's pointer and reference types; that is, for an iterator object a of class type, the same type as decltype(a.operator->()) and decltype(*a), respectively. The type iterator_traits<I>::pointer shall be void for an iterator of class type I that does not support operator->. […]

[common.iter.types]/1 slightly contradicts this:

The nested typedef-names of the specialization of iterator_traits for common_iterator<I, S> are defined as follows.

  1. […]

  2. (1.3) — If the expression a.operator->() is well-formed, where a is an lvalue of type const common_iterator<I, S>, then pointer denotes the type of that expression. Otherwise, pointer denotes void.

"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.

The most likely explanation for this contradiction is that the writer of the phrase "type of a.operator->()" was not cognizant of the difference in meaning and intended to actually write decltype(a.operator->()).

History
Date User Action Args
2023-11-22 15:47:43adminsetstatus: wp -> c++23
2022-02-10 12:58:57adminsetmessages: + msg12364
2022-02-10 12:58:57adminsetstatus: ready -> wp
2022-01-30 17:01:07adminsetmessages: + msg12309
2022-01-30 17:01:07adminsetstatus: new -> ready
2022-01-22 13:10:52adminsetmessages: + msg12272
2022-01-20 00:00:00admincreate