Title
std::optional<T&>::iterator can't be a contiguous iterator for some `T`
Status
new
Section
[optional.ref.iterators]
Submitter
Jiang An

Created on 2025-08-05.00:00:00 last changed yesterday

Messages

Date: 2025-08-29.17:49:45

Proposed resolution:

This wording is relative to N5014.

  1. Modify [optional.ref.iterators] as indicated:

    using iterator = implementation-defined; 
    

    -1- TIf `T` is an object type, this type models `contiguous_iterator` ([iterator.concept.contiguous])`random_access_iterator` ([iterator.concept.random.access]), meets the Cpp17RandomAccessIterator requirements ([random.access.iterators]), and meets the requirements for constexpr iterators ([iterator.requirements.general]), with value type remove_cv_t<T>. The reference type is T& for `iterator`. When `T` is a complete object type, iterator additionally models `contiguous_iterator` ([iterator.concept.contiguous]).
    -2- All requirements on container iterators ([container.reqmts]) apply to `optional::iterator`.

    -?- If `T` is a function type, `iterator` supports all operators required by the `random_access_iterator` concept ([iterator.concept.random.access]) along with the <=> operator as specified for container iterators ([container.reqmts]). `iterator` dereferences to a `T` lvalue. These operators behave as if `iterator` were an actual iterator iterating over a range of `T`, and result in constant subexpressions whenever the behavior is well-defined. [Note ?: Such an `optional::iterator` does not need to declare any member type because it is not an actual iterator type. — end note]

Date: 2025-08-15.00:00:00

[ 2025-08-29; Reflector poll ]

Set priority to 1 after reflector poll.

"How can `end()` work for a pointer to incomplete type? `begin`/`end` should be constrained on object types, and Mandate complete object types. The aliases shouldn't be defined for non-object types, but probably harmless."

Date: 2025-08-05.00:00:00

This is related to LWG 4304. When `T` is function type or an incomplete array type, it is impossible to implement all requirements in [optional.ref.iterators]/1.

When `T` is an incomplete object type, we may want to support std::optional<T&> as it's sometimes a replacement of `T*`. Perhaps we can require that the iterator type is always a random access iterator, and additional models `contiguous_iterator` when `T` is complete.

When `T` is a function type, the possibly intended iterator would be not even an actual iterator. But it seems that range-for loop over such an std::optional<T&> can work.

History
Date User Action Args
2025-08-29 17:49:45adminsetmessages: + msg14982
2025-08-09 15:31:12adminsetmessages: + msg14923
2025-08-05 00:00:00admincreate