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