Skip to content

Commit 2b35bc3

Browse files
committed
New issue from Jiang An: " Inconsistency between the deduction guide of std::mdspan taking (data_handle_type, mapping_type, accessor_type) and the corresponding constructor"
1 parent 81abe15 commit 2b35bc3

File tree

1 file changed

+88
-0
lines changed

1 file changed

+88
-0
lines changed

xml/issue4511.xml

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<?xml version='1.0' encoding='utf-8' standalone='no'?>
2+
<!DOCTYPE issue SYSTEM "lwg-issue.dtd">
3+
4+
<issue num="4511" status="New">
5+
<title>Inconsistency between the deduction guide of `std::mdspan` taking `(data_handle_type, mapping_type, accessor_type)`
6+
and the corresponding constructor</title>
7+
<section><sref ref="[mdspan.mdspan.overview]"/></section>
8+
<submitter>Jiang An</submitter>
9+
<date>09 Jan 2026</date>
10+
<priority>99</priority>
11+
12+
<discussion>
13+
<p>
14+
Currently, the following deduction guide of std::mdspan takes the data handle by reference:
15+
</p>
16+
<blockquote><pre>
17+
template&lt;class MappingType, class AccessorType&gt;
18+
mdspan(const typename AccessorType::data_handle_type&amp;, const MappingType&amp;,
19+
const AccessorType&amp;)
20+
-&gt; mdspan&lt;typename AccessorType::element_type, typename MappingType::extents_type,
21+
typename MappingType::layout_type, AccessorType&gt;;
22+
</pre></blockquote>
23+
<p>
24+
But the corresponding constructor takes the data handle by value:
25+
</p>
26+
<blockquote><pre>
27+
constexpr mdspan(data_handle_type p, const mapping_type&amp; m, const accessor_type&amp; a);
28+
</pre></blockquote>
29+
<p>
30+
The distinction is observable with `volatile` glvalues. E.g., in the following example,
31+
CTAD fails but explicitly specifying template arguments works
32+
(<a href="https://godbolt.org/z/fPKb9869M">demo</a>):
33+
</p>
34+
<blockquote><pre>
35+
#include &lt;cstddef&gt;
36+
#include &lt;mdspan&gt;
37+
38+
int main() {
39+
int a[1]{};
40+
int * volatile p = a;
41+
std::mdspan(
42+
p,
43+
std::layout_right::mapping&lt;std::extents&lt;std::size_t, 1&gt;&gt;{},
44+
std::default_accessor&lt;int&gt;{}); // <span style="color:red;font-weight:bolder">error (but accidentally accepted by libc++)</span>
45+
std::mdspan&lt;int, std::extents&lt;std::size_t, 1&gt;&gt;(
46+
p,
47+
std::layout_left::mapping&lt;std::extents&lt;std::size_t, 1&gt;&gt;{},
48+
std::default_accessor&lt;int&gt;{}); // OK
49+
}
50+
</pre></blockquote>
51+
<p>
52+
Given we're generally passing data handle by value, it seems better to remove <tt>const &amp;</tt> from
53+
<tt>const typename AccessorType::data_handle_type&amp;</tt> in the deduction guide, which is more
54+
consistent with the constructor and accept more seemingly valid uses.
55+
<p/>
56+
Note that libc++ is accidentally doing this now by forgetting adding the <tt>&amp;</tt>,
57+
see <a href="https://github.com/llvm/llvm-project/pull/175024">llvm/llvm-project#175024</a>.
58+
</p>
59+
</discussion>
60+
61+
<resolution>
62+
<p>
63+
This wording is relative to <paper num="N5032"/>.
64+
</p>
65+
66+
<ol>
67+
<li><p>Modify <sref ref="[mdspan.mdspan.overview]"/>, class template <tt>mdspan</tt> synopsis, as indicated:</p>
68+
69+
<blockquote>
70+
<pre>
71+
namespace std {
72+
[&hellip;]
73+
template&lt;class MappingType, class AccessorType&gt;
74+
mdspan(<del>const</del> typename AccessorType::data_handle_type<del>&amp;</del>, const MappingType&amp;,
75+
const AccessorType&amp;)
76+
-&gt; mdspan&lt;typename AccessorType::element_type, typename MappingType::extents_type,
77+
typename MappingType::layout_type, AccessorType&gt;;
78+
}
79+
</pre>
80+
</blockquote>
81+
</li>
82+
83+
</ol>
84+
85+
86+
</resolution>
87+
88+
</issue>

0 commit comments

Comments
 (0)