<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 2097: packaged_task constructors should be constrained</title>
<meta property="og:title" content="Issue 2097: packaged_task constructors should be constrained">
<meta property="og:description" content="C++ library issue. Status: C++14">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue2097.html">
<meta property="og:type" content="website">
<meta property="og:image" content="http://cplusplus.github.io/LWG/images/cpp_logo.png">
<meta property="og:image:alt" content="C++ logo">
<style>
  p {text-align:justify}
  li {text-align:justify}
  pre code.backtick::before { content: "`" }
  pre code.backtick::after { content: "`" }
  blockquote.note
  {
    background-color:#E0E0E0;
    padding-left: 15px;
    padding-right: 15px;
    padding-top: 1px;
    padding-bottom: 1px;
  }
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  table.issues-index { border: 1px solid; border-collapse: collapse; }
  table.issues-index th { text-align: center; padding: 4px; border: 1px solid; }
  table.issues-index td { padding: 4px; border: 1px solid; }
  table.issues-index td:nth-child(1) { text-align: right; }
  table.issues-index td:nth-child(2) { text-align: left; }
  table.issues-index td:nth-child(3) { text-align: left; }
  table.issues-index td:nth-child(4) { text-align: left; }
  table.issues-index td:nth-child(5) { text-align: center; }
  table.issues-index td:nth-child(6) { text-align: center; }
  table.issues-index td:nth-child(7) { text-align: left; }
  table.issues-index td:nth-child(5) span.no-pr { color: red; }
  @media (prefers-color-scheme: dark) {
     html {
        color: #ddd;
        background-color: black;
     }
     ins {
        background-color: #225522
     }
     del {
        background-color: #662222
     }
     a {
        color: #6af
     }
     a:visited {
        color: #6af
     }
     blockquote.note
     {
        background-color: rgba(255, 255, 255, .10)
     }
  }
</style>
</head>
<body>
<hr>
<p><em>This page is a snapshot from the LWG issues list, see the <a href="lwg-active.html">Library Active Issues List</a> for more information and the meaning of <a href="lwg-active.html#C++14">C++14</a> status.</em></p>
<h3 id="2097"><a href="lwg-defects.html#2097">2097</a>. <code>packaged_task</code> constructors should be constrained</h3>
<p><b>Section:</b> 32.10.10.2 <a href="https://wg21.link/futures.task.members">[futures.task.members]</a> <b>Status:</b> <a href="lwg-active.html#C++14">C++14</a>
 <b>Submitter:</b> Jonathan Wakely <b>Opened:</b> 2011-11-02 <b>Last modified:</b> 2016-01-28</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View all other</b> <a href="lwg-index.html#futures.task.members">issues</a> in [futures.task.members].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#C++14">C++14</a> status.</p>
<p><b>Discussion:</b></p>

<p>
With the proposed resolution of <a href="lwg-defects.html#2067" title="packaged_task should have deleted copy c'tor with const parameter (Status: C++14)">2067</a><sup><a href="https://cplusplus.github.io/LWG/issue2067" title="Latest snapshot">(i)</a></sup>, this no longer selects the
copy constructor:
</p>
<blockquote><pre>
std::packaged_task&lt;void()&gt; p1;
std::packaged_task&lt;void()&gt; p2(p1);
</pre></blockquote>
<p>
Instead this constructor is a better match:
</p>
<blockquote><pre>
template &lt;class F&gt;
 explicit packaged_task(F&amp;&amp; f);
</pre></blockquote>
<p>
This attempts to package a <code>packaged_task</code>, which internally tries to
copy <code>p2</code>, which fails because the copy constructor is deleted. For at
least one implementation the resulting error message is much less
helpful than the expected "cannot call deleted function" because it
happens after instantiating several more templates rather than in the
context where the constructor is called.
<p/>
I believe the solution is to constrain to the template constructors so
the template argument <code>F</code> cannot be deduced as (possibly <i>cv</i>)
<code>packaged_task&amp;</code> or <code>packaged_task</code>.  It could be argued 
this constraint is already implied because <code>packaged_task</code> is not 
copyable and the template constructors require that "invoking a copy of <code>f</code> 
shall behave the same as invoking <code>f</code>".
<p/>
Daniel points out that the variadic constructor of <code>std::thread</code>
described in 32.4.3.3 <a href="https://wg21.link/thread.thread.constr">[thread.thread.constr]</a> has a similar problem and 
suggests a similar wording change, which has been integrated below.
<p/>
An alternative is to declare <code>thread(thread&amp;)</code> and
<code>packaged_task(packaged_task&amp;)</code> as deleted.
</p>

<p><i>[2012, Portland]</i></p>

<p>
This issue appears to be more about library specification than technical
concurrency issues, so should be handled in LWG.
</p>


<p><i>[2013, Chicago]</i></p>

<p>
Move to Immediate resolution.
</p>
<p>
Howard volunteered existing implementation experience with the first change, and saw no issue that the second would 
introduce any new issue.
</p>



<p id="res-2097"><b>Proposed resolution:</b></p>
<p>This wording is relative to the FDIS.</p>

<ol>
<li><p>Insert a new Remarks element to 32.4.3.3 <a href="https://wg21.link/thread.thread.constr">[thread.thread.constr]</a> around p3 as indicated:</p>

<blockquote><pre>
template &lt;class F, class ...Args&gt; explicit thread(F&amp;&amp; f, Args&amp;&amp;... args);
</pre></blockquote>
<p>
-3- <i>Requires</i>: <code>F</code> and each <code>Ti</code> in <code>Args</code> shall satisfy the <code>MoveConstructible</code> 
requirements. <code><i>INVOKE</i>(<i>DECAY_COPY</i> ( std::forward&lt;F&gt;(f)), <i>DECAY_COPY</i> (std::forward&lt;Args&gt;(args))...)</code> 
(20.8.2) shall be a valid expression.
<p/>
<ins>-?- <i>Remarks</i>: This constructor shall not participate in overload resolution if <code>decay&lt;F&gt;::type</code> 
is the same type as <code>std::thread</code>.</ins>
</p>
</li>

<li><p>Insert a new Remarks element to 32.10.10.2 <a href="https://wg21.link/futures.task.members">[futures.task.members]</a> around p2 as indicated:</p>

<blockquote><pre>
template &lt;class F&gt;
  packaged_task(F&amp;&amp; f);
template &lt;class F, class Allocator&gt;
  explicit packaged_task(allocator_arg_t, const Allocator&amp; a, F&amp;&amp; f);
</pre></blockquote>
<p>
-2- <i>Requires</i>: <code><i>INVOKE</i>(f, t1, t2, ..., tN, R)</code>, where <code>t1, t2, ..., tN</code> are values of the corresponding
types in <code>ArgTypes...</code>, shall be a valid expression. Invoking a copy of <code>f</code> shall behave the same as invoking <code>f</code>.
<p/>
<ins>-?- <i>Remarks</i>: These constructors shall not participate in overload resolution if <code>decay&lt;F&gt;::type</code> 
is the same type as <code>std::packaged_task&lt;R(ArgTypes...)&gt;</code>.</ins>
</p>
</li>

</ol>






</body>
</html>
