This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++20 status.
span::cbegin/cend methods produce different results than std::[ranges::]cbegin/cendSection: 23.7.2.2.7 [span.iterators] Status: C++20 Submitter: Poland Opened: 2019-11-06 Last modified: 2021-02-25
Priority: 0
View all issues with C++20 status.
Discussion:
Addresses PL 247
span<T> provides a const-qualified begin() method and cbegin()
method that produces a different result if T is not const-qualifed:
begin() produces mutable iterator over T (as if T*)
cbegin() produces const iterator over T (as if T const*)
As consequence for the object s of type span<T>, the call to the
std::cbegin(s)/std::ranges::cbegin(s) produces different result than s.cbegin().
span<T> members cbegin()/cend()/crbegin()/crend()/const_iterator
to be equivalent to begin()/end()/rbegin()/rend()/iterator respectively.
Tomasz Kamiński:
Per LEWG discussion in Belfast these methods and related typedefs should be removed.[2019-11 Status to Ready during Wednesday night issue processing in Belfast.]
Proposed resolution:
This wording is relative to N4835.
Modify 23.7.2.2.1 [span.overview], class template span synopsis, as indicated:
namespace std {
template<class ElementType, size_t Extent = dynamic_extent>
class span {
public:
// constants and types
using element_type = ElementType;
using value_type = remove_cv_t<ElementType>;
using index_type = size_t;
using difference_type = ptrdiff_t;
using pointer = element_type*;
using const_pointer = const element_type*;
using reference = element_type&;
using const_reference = const element_type&;
using iterator = implementation-defined; // see 23.7.2.2.7 [span.iterators]
using const_iterator = implementation-defined;
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
static constexpr index_type extent = Extent;
[…]
// 23.7.2.2.7 [span.iterators], iterator support
constexpr iterator begin() const noexcept;
constexpr iterator end() const noexcept;
constexpr const_iterator cbegin() const noexcept;
constexpr const_iterator cend() const noexcept;
constexpr reverse_iterator rbegin() const noexcept;
constexpr reverse_iterator rend() const noexcept;
constexpr const_reverse_iterator crbegin() const noexcept;
constexpr const_reverse_iterator crend() const noexcept;
friend constexpr iterator begin(span s) noexcept { return s.begin(); }
friend constexpr iterator end(span s) noexcept { return s.end(); }
[…]
};
[…]
}
Modify 23.7.2.2.7 [span.iterators] as indicated:
using iterator = implementation-defined;using const_iterator = implementation-defined;[…]-1- The type
smodelscontiguous_iterator(24.3.4.14 [iterator.concept.contiguous]), meets the Cpp17RandomAccessIterator requirements (24.3.5.7 [random.access.iterators]), and meets the requirements for constexpr iterators (24.3.1 [iterator.requirements.general]). All requirements on container iterators (23.2 [container.requirements]) apply tospan::iteratorandas well.span::const_iteratorconstexpr const_iterator cbegin() const noexcept;
-6- Returns: A constant iterator referring to the first element in the span. Ifempty()istrue, then it returns the same value ascend().constexpr const_iterator cend() const noexcept;
-7- Returns: A constant iterator which is the past-the-end value.constexpr const_reverse_iterator crbegin() const noexcept;
-8- Effects: Equivalent to:return const_reverse_iterator(cend());constexpr const_reverse_iterator crend() const noexcept;
-9- Effects: Equivalent to:return const_reverse_iterator(cbegin());