Skip to content

Commit 464db4b

Browse files
tomaszkamjwakely
authored andcommitted
New issue: "move_only_function constructor should recognize empty copyable_functions"
1 parent 1fcc1c9 commit 464db4b

File tree

1 file changed

+74
-0
lines changed

1 file changed

+74
-0
lines changed

xml/issue4255.xml

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<?xml version='1.0' encoding='utf-8' standalone='no'?>
2+
<!DOCTYPE issue SYSTEM "lwg-issue.dtd">
3+
4+
<issue num="4255" status="New">
5+
<title>move_only_function constructor should recognize empty copyable_functions</title>
6+
<section><sref ref="[func.wrap.move.ctor]"/></section>
7+
<submitter>Tomasz Kami&nacute;ski</submitter>
8+
<date>12 May 2025</date>
9+
<priority>99</priority>
10+
11+
<discussion>
12+
<p>
13+
The standard currently requires that constructing <code>move_only_function</code>
14+
from empty <code>copyable_function</code>, creates an non-empty <code>move_only_function</code>,
15+
that contains an empty <code>copyable_function</code> as the target. For exampe:
16+
<code>
17+
std::copyable_function&lt;int(int)&gt; ce;
18+
std::move_only_function&lt;int(int)&gt; me(ce);
19+
</code>
20+
We require that invoking <code>me(1)</code> is undefined behavior (as it leads to call to the
21+
<code>ce(1)</code>), however it cannot be detected in the user code, as <code>me != nullptr</code>
22+
is true.
23+
</p>
24+
25+
<p>
26+
We should require that the <code>move_only_function(F&amp;&amp; f)</code> constructor to create an
27+
empty object, if <code>f</code> is instantiation of of <code>copyable_function</code> and
28+
<code>f == nullptr</code> is true, i.e. f does not contain target object.
29+
</p>
30+
31+
<p>
32+
This simplifies implementing avoidance of double wrapping per <sref ref="[func.wrap.general]"/> p2,
33+
as transfering the target produces empty functor.
34+
</p>
35+
36+
<p>
37+
The <code>copyable_function</code> cannot be constructed from <code>move_only_function</code>,
38+
as it requires functor to be copyable. Invkoing an empty <code>std::function</code> has well
39+
defined behavior (throws <code>bad_function_call</code>), and wrapping such object into
40+
other functors should reproduce that behavior
41+
</p>
42+
43+
</discussion>
44+
45+
<resolution>
46+
<p>
47+
This wording is relative to <paper num="N5008"/>.
48+
</p>
49+
<ol>
50+
51+
<li><p>Modify <sref ref="[func.wrap.general]"/> as indicated:</p>
52+
53+
<blockquote>
54+
<pre>
55+
template&lt;class F&gt; move_only_function(F&amp;&amp; f);
56+
</pre>
57+
<blockquote>
58+
[&hellip;]
59+
<p>-8- <i>Postconditions:</i>: <tt>*this</tt> has no target object if any of the following hold:</p>
60+
<ul>
61+
<li><p>(8.1) <tt>f</tt> is a null function pointer value, <del>or</del></p></li>
62+
<li><p>(8.2) <tt>f</tt> is a null member pointer value, or</p></li>
63+
<li><p>(8.2) <tt>remove_cvref_t&lt;F&gt;</tt> is a specialization of the <tt>move_only_function</tt>
64+
<ins>or <tt>copyable_function</tt></ins> class template, and <tt>f</tt> has no target object.</p></li>
65+
</ul>
66+
</blockquote>
67+
</blockquote>
68+
69+
</li>
70+
</ol>
71+
72+
</resolution>
73+
74+
</issue>

0 commit comments

Comments
 (0)