---
title: Comparisons for span
document: P4216R0
date: 2026-05-07
audience: LEWG
reply-to:
  - "Michael Florian Hava  < <mfh.cpp@gmail.com>"
  - "1"
paper-type: proposal
---

Document number: P4216R0 Date: 2026-05-07 Project: Programming Language C++ Audience: LEWG Reply-to: Michael Florian Hava [<mfh.cpp@gmail.com>](mailto:mfh.cpp@gmail.com) 1

# Comparisons for `span`

**Design Space** **Deep value comparisons** All existing *reference types* use the same comparison model: they compare the referenced values (if any), not their identity. This model has always been in place for `string_view` and was adopted

**Before** **Proposed** `reference_wrapper``<``int``> r0 = …, r1 = …;` `optional``<``int``&> o0 = …, o1 = …;` `string_view` `s0 = …, s1 = …;` `span``<``T``> p0 = …, p1 …;` `reference_wrapper``<``int``> r0 = …, r1 = …;` `optional``<``int``&> o0 = …, o1 = …;` `string_view` `s0 = …, s1 = …;` `span``<``T``> p0 = …, p1 …;`

```cpp
//equality comparisons: 
//NOTE: all of these do „deep value comparisons“ 
r0 == r1; 
o0 == o1; 
s0 == s1; 
ranges::equal(p0, p1);
                                                    //equality comparisons: 
                                                    //NOTE: all of these do „deep value comparisons“ 
                                                    r0 == r1; 
                                                    o0 == o1; 
                                                    s0 == s1; 
                                                    p0 == p1;
```

`//three-way comparisons:` `//NOTE: all of these do „deep value comparisons“` `r0` `<=>` `r1;` `o0` `<=>` `o1;` `s0` `<=>` `s1;` `lexicographical_compare_three_way``(` `p0.``begin``(), p0.``end``(),` `p1.``begin``(), p1.``end``(),` `synth-three-way` `//but that’s exposition-only` 😬 `);`

```cpp
//three-way comparisons: 
//NOTE: all of these do „deep value comparisons“ 
r0 <=> r1; 
o0 <=> o1; 
s0 <=> s1; 
p0 <=> p1;
```

[RISC Software GmbH, Softwarepark 32a, 4232 Hagenberg, Austria, michael.hava@risc-software.at](mailto:michael.hava@risc-software.at) 1

1 for `optional<T&>` and `reference_wrapper` [in C++26 with [P2988] and [P2944] respectively. We](http://wg21.link/P2944) propose to adopt this model for `span`.

**Why** `span` **isn’t already comparable?** The original proposal for `span` [([P0122]) included comparisons, modelling deep value](http://wg21.link/P0122) comparisons. It was adopted in Jacksonville in March 2018. In October of the same year they [were removed in the San Diego meeting by [P1085].](http://wg21.link/p1085)

The concerns of P1085 can be summarised as: `span` …

* … has „reference semantics“, therefore it’s value can change transparently.

* … does not enforce deep const (note, that there is no discussion on `span<const T>`).

* … rebinds on assignment.

All these concerns are real. What P1085 doesn’t acknowledge is that all but the second concern equally apply to `string_view`, neither does it make a convincing case for why these concerns are in any way alleviated by removing comparisons!

Furthermore, all these concerns are the correct semantics for a *reference* type! It took us close to a decade to come to the conclusion that rebinding assignment is exactly the right thing for `optional<T&>` to do. The same design was chosen for `reference_wrapper` and `function_ref`. We therefore see no point in not providing comparisons for `span`.

## Impact on the Standard

## Proposed Wording

### [version.syn]

### [span.syn]

## Acknowledgements

:::wording-add

<ins>#define __cpp_lib_span_comparison YYYYMML //freestanding, also in <span></ins>

:::

**[DRAFTING NOTE: Adjust the placeholder value as needed to denote the proposal’s date of adoption.]**

**??.?.?.? Header** `<span>` **synopsis** **[span.syn]**

:::wording-add

// mostly freestanding namespace std { … // [views.span], class template span template<class ElementType, size_t Extent = dynamic_extent> class span; <ins>template<class ElementType, size_t Extent></ins> <ins>constexpr bool operator==(span<ElementType, Extent> x, span<ElementType, Extent> y);</ins> <ins>template<class ElementType, size_t Extent></ins> <ins>constexpr synth-three-way-result<ElementType></ins> <ins>operator<=>(span<ElementType, Extent> x, span<ElementType, Extent> y);</ins> template<class ElementType, size_t Extent> constexpr bool ranges::enable_view<span<ElementType, Extent>> = true; … }

:::

```cpp
[DRAFTING NOTE: We assume that these changes are enough to „trigger“ [container.reqmts-44] and 
[container.opt.reqmts-4]]
```

### 2
