3813. std::span<volatile T, E> is made ill-formed by P2278R4 when T is a normal class type

Section: 23.7.2.2.1 [span.overview] Status: New Submitter: Jiang An Opened: 2022-11-06 Last modified: 2022-11-12

Priority: 2

View all other issues in [span.overview].

View all issues with New status.

Discussion:

This issue is discovered when implementing the span part of P2278R4 in MSVC STL.

P2278R4 added the const_iterator member type to std::span, which required its iterator type to model std::input_iterator (same for const_reverse_iterator and reverse_iterator).

However, when element_type is volatile T and T is a class type, the iterator type generally fails to satisfy input_iterator, because:

  1. input_iterator<iterator> requires indirectly_readable<iterator>;

  2. indirectly_readable<iterator> requires common_reference_with<iterator_reference_t<iterator>&&, iterator_rvalue_reference_t<iterator>&&>, that is common_reference_with<volatile T&, volatile T&&>;

  3. common_reference_t<volatile T&, volatile T&&> is T (which is problematic), and thus common_reference_with<volatile T&, volatile T&&> requires both convertible_to<volatile T&, T> and convertible_to<volatile T&&, T>;

  4. However, the class type T generally doesn't have constructors from volatile T or const volatile T glvalues, and thus neither convertible_to<volatile T&, T> and convertible_to<volatile T&&, T> is satisfied.

Ideally, span should not require any form of construction of element_type. Although usages of class types provided by the standard library via volatile glvalues are generally not supported, I think span<volatile T, E> is still useful for some user-defined class type T, and thus shouldn't be forbidden.

[Kona 2022-11-12; Set priority to 2]

Proposed resolution: