Skip to content

Commit d67149f

Browse files
committed
New issue from Jiang An: "std::atomic_ref<const T> can be constructed from temporaries"
1 parent 4eae817 commit d67149f

File tree

1 file changed

+131
-0
lines changed

1 file changed

+131
-0
lines changed

xml/issue4472.xml

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
<?xml version='1.0' encoding='utf-8' standalone='no'?>
2+
<!DOCTYPE issue SYSTEM "lwg-issue.dtd">
3+
4+
<issue num="4472" status="New">
5+
<title><tt>std::atomic_ref&lt;const T&gt;</tt> can be constructed from temporaries</title>
6+
<section><sref ref="[atomics.ref.generic]"/></section>
7+
<submitter>Jiang An</submitter>
8+
<date>11 Nov 2025</date>
9+
<priority>99</priority>
10+
11+
<discussion>
12+
<p>
13+
<tt>std::atomic_ref&lt;T&gt;</tt> has a constructor taking <tt>T&amp;</tt>, so when `T` is a `const`
14+
but not `volatile` object type, the constructor parameter can be bound to a temporary expression,
15+
which doesn't seem to make sense. Even after <paper num="P3860R1"/>, explicitly constructing
16+
<tt>std::atomic_ref&lt;const T&gt;</tt> from <tt>std::atomic_ref&lt;volatile T&gt;</tt> can be
17+
well-formed with the undesired semantics when it is well-formed to instantiate
18+
<tt>std::atomic_ref&lt;volatile T&gt;</tt> and its operator `T` conversion function, because the
19+
construction calls the conversion function and creates a temporary object. Probably it's better
20+
to disallow such reference binding.
21+
</p>
22+
</discussion>
23+
24+
<resolution>
25+
<p>
26+
This wording is relative to <paper num="N5014"/> after application of <paper num="P3860R1"/>.
27+
</p>
28+
29+
<blockquote class="note">
30+
<p>
31+
[<i>Drafting note</i>: The deleted overloads were mirrored from the design of `reference_wrapper` before
32+
LWG <iref ref="2993"/>. As these overloads don't participate in implicit conversion, I don't think there
33+
will be any similar issue introduced.]
34+
</p>
35+
</blockquote>
36+
37+
<ol>
38+
<li><p>Modify <sref ref="[atomics.ref.generic.general]"/>, primary class template `atomic_ref` synopsis, as indicated:</p>
39+
40+
<blockquote>
41+
<pre>
42+
namespace std {
43+
template&lt;class T&gt; struct atomic_ref {
44+
private:
45+
T* ptr; <i>// exposition only</i>
46+
public:
47+
[&hellip;]
48+
constexpr explicit atomic_ref(T&amp;);
49+
<ins>explicit atomic_ref(T&amp;&amp;) = delete;</ins>
50+
constexpr atomic_ref(const atomic_ref&amp;) noexcept;
51+
template&lt;class U&gt;
52+
constexpr atomic_ref(const atomic_ref&lt;U&gt;&amp;) noexcept;
53+
[&hellip;]
54+
};
55+
}
56+
</pre>
57+
</blockquote>
58+
</li>
59+
60+
<li><p>Modify <sref ref="[atomics.ref.int]"/>, class template `atomic_ref` <tt><i>integral-type</i></tt>
61+
specialization synopsis, as indicated:</p>
62+
63+
<blockquote>
64+
<pre>
65+
namespace std {
66+
template&lt;&gt; struct atomic_ref&lt;<i>integral-type</i>&gt; {
67+
private:
68+
<i>integral-type</i>* ptr; <i>// exposition only</i>
69+
public:
70+
[&hellip;]
71+
constexpr explicit atomic_ref(<i>integral-type</i>&amp;);
72+
<ins>explicit atomic_ref(<i>integral-type</i>&amp;&amp;) = delete;</ins>
73+
constexpr atomic_ref(const atomic_ref&amp;) noexcept;
74+
template&lt;class U&gt;
75+
constexpr atomic_ref(const atomic_ref&lt;U&gt;&amp;) noexcept;
76+
[&hellip;]
77+
};
78+
}
79+
</pre>
80+
</blockquote>
81+
</li>
82+
83+
<li><p>Modify <sref ref="[atomics.ref.float]"/>, class template `atomic_ref` <tt><i>floating-point-type</i></tt>
84+
specialization synopsis, as indicated:</p>
85+
86+
<blockquote>
87+
<pre>
88+
namespace std {
89+
template&lt;&gt; struct atomic_ref&lt;<i>floating-point-type</i>&gt; {
90+
private:
91+
<i>floating-point-type</i>* ptr; <i>// exposition only</i>
92+
public:
93+
[&hellip;]
94+
constexpr explicit atomic_ref(<i>floating-point-type</i>&amp;);
95+
<ins>explicit atomic_ref(<i>floating-point-type</i>&amp;&amp;) = delete;</ins>
96+
constexpr atomic_ref(const atomic_ref&amp;) noexcept;
97+
template&lt;class U&gt;
98+
constexpr atomic_ref(const atomic_ref&lt;U&gt;&amp;) noexcept;
99+
[&hellip;]
100+
};
101+
}
102+
</pre>
103+
</blockquote>
104+
</li>
105+
106+
<li><p>Modify <sref ref="[atomics.ref.pointer]"/>, class template `atomic_ref` <tt><i>pointer-type</i></tt>
107+
specialization synopsis, as indicated:</p>
108+
109+
<blockquote>
110+
<pre>
111+
namespace std {
112+
template&lt;&gt; struct atomic_ref&lt;<i>pointer-type</i>&gt; {
113+
private:
114+
<i>pointer-type</i>* ptr; <i>// exposition only</i>
115+
public:
116+
[&hellip;]
117+
constexpr explicit atomic_ref(<i>pointer-type</i>&amp;);
118+
<ins>explicit atomic_ref(<i>pointer-type</i>&amp;&amp;) = delete;</ins>
119+
constexpr atomic_ref(const atomic_ref&amp;) noexcept;
120+
template&lt;class U&gt;
121+
constexpr atomic_ref(const atomic_ref&lt;U&gt;&amp;) noexcept;
122+
[&hellip;]
123+
};
124+
}
125+
</pre>
126+
</blockquote>
127+
</li>
128+
</ol>
129+
</resolution>
130+
131+
</issue>

0 commit comments

Comments
 (0)