Skip to content

Commit 4b5d1c6

Browse files
committed
New issue from Arthur O'Dwyer: "List-initialization of iterators in [simd.mask.overview]"
1 parent 146db26 commit 4b5d1c6

File tree

1 file changed

+120
-0
lines changed

1 file changed

+120
-0
lines changed

xml/issue4402.xml

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
<?xml version='1.0' encoding='utf-8' standalone='no'?>
2+
<!DOCTYPE issue SYSTEM "lwg-issue.dtd">
3+
4+
<issue num="4402" status="New">
5+
<title>List-initialization of iterators in [simd.mask.overview]</title>
6+
<section>
7+
<sref ref="[simd.mask.overview]"/>
8+
</section>
9+
<submitter>Arthur O'Dwyer</submitter>
10+
<date>02 Oct 2025</date>
11+
<priority>99</priority>
12+
13+
<discussion>
14+
<p>
15+
<sref ref="[simd.mask.overview]"/> has
16+
</p>
17+
<blockquote><pre>
18+
namespace std::simd {
19+
template&lt;class V&gt;
20+
class <i>simd-iterator</i> { // exposition only
21+
V* <i>data_</i> = nullptr; // exposition only
22+
<i>simd-size-type</i> <i>offset_</i> = 0; // exposition only
23+
<b>constexpr <i>simd-iterator</i>(V&amp; d, <i>simd-size-type</i> off) noexcept; // <i>exposition only</i></b>
24+
[&hellip;]
25+
};
26+
[&hellip;]
27+
template&lt;size_t Bytes, class Abi&gt;
28+
class basic_mask {
29+
public:
30+
using value_type = bool;
31+
using abi_type = Abi;
32+
using iterator = <i>simd-iterator</i>&lt;basic_mask&gt;;
33+
using const_iterator = <i>simd-iterator</i>&lt;const basic_mask&gt;;
34+
<b>constexpr iterator begin() noexcept { return {*this, 0}; }</b>
35+
constexpr const_iterator begin() const noexcept { return {*this, 0}; }
36+
constexpr const_iterator cbegin() const noexcept { return {*this, 0}; }
37+
constexpr default_sentinel_t end() const noexcept { return {}; }
38+
constexpr default_sentinel_t cend() const noexcept { return {}; }
39+
[&hellip;]
40+
</pre></blockquote>
41+
<p>
42+
It's unclear whether the "exposition-only" constructor is required to be present. If it is present,
43+
as written, without `explicit`, then `{someBasicMask, 0}` becomes a valid initializer for an iterator.
44+
Evidence in favor of its intentionality: the use of `return {*this, 0}` in `basic_mask::begin()`.
45+
(The constructor is `private`, but it still participates in overload resolution and will ambiguate
46+
other possible conversions.) But this makes many expressions ambiguous that could be unambiguous to a human.
47+
</p>
48+
<blockquote><pre>
49+
using Mask = std::simd::mask&lt;int&gt;;
50+
51+
void overloaded(std::string, std::pair&lt;Mask, int&gt; kv);
52+
void overloaded(std::string, Mask::iterator it);
53+
54+
int main() {
55+
Mask m;
56+
overloaded("the pair is", {m, 0}); // ambiguous?
57+
}
58+
</pre></blockquote>
59+
<p>
60+
At the very least, we should say that this list-initialization is intentional, and add wording to
61+
class <tt><i>simd-iterator</i></tt> and/or remove the "exposition only" from <tt><i>simd-iterator</i></tt>'s
62+
constructor. That makes it clear that the above program is indeed intended to be ambiguous. But IMO
63+
we should instead simply make the above program valid.
64+
</p>
65+
</discussion>
66+
67+
<resolution>
68+
<p>
69+
This wording is relative to <paper num="N5014"/>.
70+
</p>
71+
72+
<ol>
73+
74+
<li><p>Modify <sref ref="[simd.iterator]"/> as indicated:</p>
75+
76+
<blockquote>
77+
<pre>
78+
namespace std::simd {
79+
template&lt;class V&gt;
80+
class <i>simd-iterator</i> { // <i>exposition only</i>
81+
V* <i>data_</i> = nullptr; // <i>exposition only</i>
82+
<i>simd-size-type</i> <i>offset_</i> = 0; // <i>exposition only</i>
83+
constexpr <ins>explicit</ins> <i>simd-iterator</i>(V&amp; d, <i>simd-size-type</i> off) noexcept; // <i>exposition only</i>
84+
85+
[&hellip;]
86+
};
87+
}
88+
</pre>
89+
</blockquote>
90+
</li>
91+
92+
<li><p>Modify <sref ref="[simd.mask.overview]"/> as indicated:</p>
93+
94+
<blockquote>
95+
<pre>
96+
namespace std::simd {
97+
template&lt;size_t Bytes, class Abi&gt; class basic_mask {
98+
public:
99+
using value_type = bool;
100+
using abi_type = Abi;
101+
using iterator = <i>simd-iterator</i>&lt;basic_mask&gt;;
102+
using const_iterator = <i>simd-iterator</i>&lt;const basic_mask&gt;;
103+
constexpr iterator begin() noexcept { return <ins>iterator(</ins><del>{</del>*this, 0<del>}</del><ins>)</ins>; }
104+
constexpr const_iterator begin() const noexcept { return <ins>const_iterator(</ins><del>{</del>*this, 0<del>}</del><ins>)</ins>; }
105+
constexpr const_iterator cbegin() const noexcept { return <ins>const_iterator(</ins><del>{</del>*this, 0<del>}</del><ins>)</ins>; }
106+
constexpr default_sentinel_t end() const noexcept { return {}; }
107+
constexpr default_sentinel_t cend() const noexcept { return {}; }
108+
109+
[&hellip;]
110+
};
111+
}
112+
</pre>
113+
</blockquote>
114+
</li>
115+
116+
</ol>
117+
118+
</resolution>
119+
120+
</issue>

0 commit comments

Comments
 (0)