Skip to content

Commit 27bbfd9

Browse files
committed
New issue from Hewill: "Should span(R&&) CTAD apply P2280?"
1 parent a59be59 commit 27bbfd9

File tree

1 file changed

+113
-0
lines changed

1 file changed

+113
-0
lines changed

xml/issue4404.xml

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
<?xml version='1.0' encoding='utf-8' standalone='no'?>
2+
<!DOCTYPE issue SYSTEM "lwg-issue.dtd">
3+
4+
<issue num="4404" status="New">
5+
<title>Should <code>span(R&amp;&amp;)</code> CTAD apply P2280?</title>
6+
<section>
7+
<sref ref="[span.deduct]"/>
8+
</section>
9+
<submitter>Hewill Kang</submitter>
10+
<date>04 Oct 2025</date>
11+
<priority>99</priority>
12+
13+
<discussion>
14+
<p>
15+
Thanks to <paper num="P2280R4"/>, `simd::basic_vec`'s CTAD can specify template parameters
16+
directly through `ranges::size`:
17+
</p>
18+
<blockquote><pre>
19+
basic_vec(R&amp;&amp; r, ...) -&gt; vec&lt;ranges::range_value_t&lt;R&gt;, ranges::size(r)&gt;
20+
</pre></blockquote>
21+
<p>
22+
However, <code>span</code> with similar CTAD forms do not have this automatic static size optimization applied:
23+
</p>
24+
<blockquote><pre>
25+
span(R&amp;&amp;) -&gt; span&lt;remove_reference_t&lt;ranges::range_reference_t&lt;R&gt;&gt;&gt;;
26+
</pre></blockquote>
27+
<p>
28+
Do we need to do it for <code>span</code>?
29+
<p/>
30+
Note that the `span` constructor actually requires `R` to be a `contiguous_range` and a
31+
`sized_range`. If it is further required that `ranges::size` be a constant expression, only raw array,
32+
`array`, `span`, `ranges::empty_view`, and `ranges::single_view` satisfy this requirement.
33+
Given that `span` already has CTAD for raw arrays and `array`s, this improvement is not
34+
significant, but it still seems worthwhile as a compile-time optimization for certain
35+
user-defined types or in some specialized cases (<a href="https://godbolt.org/z/EW6xnnfe1">demo</a>):
36+
</p>
37+
<blockquote><pre>
38+
#include &lt;array&gt;
39+
#include &lt;ranges&gt;
40+
41+
constexpr std::size_t N = 42;
42+
43+
auto to_span(auto&amp; r) {
44+
static_assert(std::ranges::size(r) == N); // ok after P2280
45+
return std::span(r);
46+
}
47+
48+
std::array&lt;int, N&gt; a;
49+
auto s1 = to_span(a);
50+
static_assert(std::same_as&lt;decltype(s1), std::span&lt;int, N&gt;&gt;);
51+
52+
auto r = std::array&lt;int, N&gt;{} | std::views::as_const; // as_const_view&lt;owning_view&lt;array&lt;int, N&gt;&gt;&gt;
53+
auto s2 = to_span(r);
54+
static_assert(std::same_as&lt;decltype(s2), std::span&lt;const int, N&gt;&gt;); // <span style="color:red;font-weight:bolder">fire, ok after this PR</span>
55+
</pre></blockquote>
56+
</discussion>
57+
58+
<resolution>
59+
<p>
60+
This wording is relative to <paper num="N5014"/>.
61+
</p>
62+
63+
<ol>
64+
65+
<li><p>Modify <sref ref="[span.overview]"/> as indicated:</p>
66+
67+
<blockquote>
68+
<pre>
69+
namespace std {
70+
template&lt;class ElementType, size_t Extent = dynamic_extent&gt;
71+
class span {
72+
[&hellip;]
73+
};
74+
[&hellip;]
75+
template&lt;class R&gt;
76+
span(R&amp;&amp; <ins>r</ins>) -&gt; <ins><i>see below</i></ins><del>span&lt;remove_reference_t&lt;ranges::range_reference_t&lt;R&gt;&gt;&gt;</del>;
77+
}
78+
</pre>
79+
</blockquote>
80+
</li>
81+
82+
<li><p>Modify <sref ref="[span.deduct]"/> as indicated:</p>
83+
84+
<blockquote>
85+
<pre>
86+
template&lt;class R&gt;
87+
span(R&amp;&amp; <ins>r</ins>) -&gt; <ins><i>see below</i></ins><del>span&lt;remove_reference_t&lt;ranges::range_reference_t&lt;R&gt;&gt;&gt;</del>;
88+
</pre>
89+
<blockquote>
90+
<p>
91+
-2- <i>Constraints</i>: `R` satisfies `ranges::contiguous_range`.
92+
<p/>
93+
<ins>-?- <i>Remarks</i>: Let `T` denote the type <code>remove_reference_t&lt;ranges::range_reference_t&lt;R&gt;&gt;</code>.
94+
The deduced type is equivalent to</ins>
95+
</p>
96+
<ol style="list-style-type: none">
97+
<li><p>
98+
<ins>(?.1) &mdash; <code>span&lt;T, static_cast&lt;size_t&gt;(ranges::size(r))&gt;</code>
99+
if `R` satisfies `ranges::sized_range` and `ranges::size(r)` is a constant expression.</ins>
100+
</p></li>
101+
<li><p>
102+
<ins>(?.2) &mdash; <code>span&lt;T&gt;</code> otherwise.</ins>
103+
</p></li>
104+
</ol>
105+
</blockquote>
106+
</blockquote>
107+
</li>
108+
109+
</ol>
110+
111+
</resolution>
112+
113+
</issue>

0 commit comments

Comments
 (0)