forked from cplusplus/LWG
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathissue4256.xml
More file actions
84 lines (72 loc) · 2.6 KB
/
issue4256.xml
File metadata and controls
84 lines (72 loc) · 2.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
<?xml version='1.0' encoding='utf-8' standalone='no'?>
<!DOCTYPE issue SYSTEM "lwg-issue.dtd">
<issue num="4256" status="New">
<title>Incorrect constrains for <code>function_ref</code> constructors from <code>nontype_t</code></title>
<section><sref ref="[func.wrap.ref.ctor]"/></section>
<submitter>Tomasz Kamiński</submitter>
<date>14 May 2025</date>
<priority>99</priority>
<discussion>
<p>
For the following class:
</p>
<pre>
struct M
{
void operator();
};
</pre>
<p>
The constructor of <code>function_ref<void()></code> from <code>nontype_t</code>
is considered to be valid candidate
(is_constructible_v<function_ref<void()>, nontype_t<M{}>> is <code>true</code>),
despite the fact that the corresponding invocation of template argument object, that is const lvalue,
is ill-formed. As consequence we produce hard error from inside of this constructor.
</p>
<p>
This is caused by the fact that for constructors with non-type <code>auto f</code> parameter,
we are checking if <code><i>is-invocable-using</i><F></code> is <code>true</code>,
where <code>F</code> is <code>decltype(f)</code> i.e. <code>M</code> for the example.
We should use <code>const F&</code> or <code>decltype((f))</code>.
</p>
</discussion>
<resolution>
<p>
This wording is relative to <paper num="N5008"/>.
</p>
<ol>
<li><p>Modify <sref ref="[func.wrap.ref.ctor]"/> as indicated:</p>
<blockquote>
<pre>
template<auto f> constexpr function_ref(nontype_t<f>) noexcept;
</pre>
<blockquote>
<p>-8- Let <tt>F</tt> be <tt>decltype(f)</tt>.</p>
<p>-9- <i>Constraints</i>: <tt><i>is-invocable-using</i><<ins>const </ins>F<ins>&</ins>></tt> is <tt>true</tt>.</p>
[…]
</blockquote>
<pre>
template<auto f, class U> constexpr function_ref(nontype_t<f>, U&& obj) noexcept;
</pre>
<blockquote>
<p>-12- Let <tt>T</tt> be <tt>remove_reference_t<U></tt> and <tt>F</tt> be <tt>decltype(f)</tt>.</p>
<p>-13- <i>Constraints:</i>:</p>
<ul>
<li><p>(13.1) <tt>is_rvalue_reference_v<U&&></tt> is false, and</p></li>
<li><p>(13.2) <tt><i>is-invocable-using</i><<ins>const </ins>F<ins>&</ins>, T <i>cv</i>&></tt> is <tt>true</tt>.</p></li>
</ul>
[…]
</blockquote>
<pre>
template<auto f, class T> constexpr function_ref(nontype_t<f>, T <i>cv</i>* obj) noexcept;
</pre>
<blockquote>
<p>-17- Let <tt>F</tt> be <tt>decltype(f)</tt>.</p>
<p>-16- <i>Constraints</i>: <tt><i>is-invocable-using</i><<ins>const </ins>F<ins>&</ins>, T <i>cv</i>*></tt> is <tt>true</tt>.</p>
[…]
</blockquote>
</blockquote>
</li>
</ol>
</resolution>
</issue>