<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 2095: promise and packaged_task missing constructors needed for uses-allocator construction</title>
<meta property="og:title" content="Issue 2095: promise and packaged_task missing constructors needed for uses-allocator construction">
<meta property="og:description" content="C++ library issue. Status: Resolved">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue2095.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#Resolved">Resolved</a> status.</em></p>
<h3 id="2095"><a href="lwg-defects.html#2095">2095</a>. <code>promise</code> and <code>packaged_task</code> missing constructors needed for uses-allocator construction</h3>
<p><b>Section:</b> 32.10.6 <a href="https://wg21.link/futures.promise">[futures.promise]</a>, 32.10.10 <a href="https://wg21.link/futures.task">[futures.task]</a> <b>Status:</b> <a href="lwg-active.html#Resolved">Resolved</a>
 <b>Submitter:</b> Jonathan Wakely <b>Opened:</b> 2011-11-01 <b>Last modified:</b> 2025-06-23</p>
<p><b>Priority: </b>4
</p>
<p><b>View all other</b> <a href="lwg-index.html#futures.promise">issues</a> in [futures.promise].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#Resolved">Resolved</a> status.</p>
<p><b>Discussion:</b></p>

<p>
This example is ill-formed according to C++11 because <code>uses_allocator&lt;promise&lt;R&gt;, A&gt;::value</code> is true, but
<code>is_constructible&lt;promise&lt;R&gt;, A, promise&lt;R&gt;&amp;&amp;&gt;::value</code> is false. Similarly for <code>packaged_task</code>.
</p>
<blockquote><pre>
#include &lt;future&gt;
#include &lt;memory&gt;
#include &lt;tuple&gt;

using namespace std;

typedef packaged_task&lt;void()&gt; task;
typedef promise&lt;void&gt; prom;
allocator&lt;task&gt; a;

tuple&lt;task, prom&gt; t1{ allocator_arg, a };
tuple&lt;task, prom&gt; t2{ allocator_arg, a, task{}, prom{} };
</pre></blockquote>

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

<p>
This is an allocator issue, and should be dealt with directly by LWG.
</p>

<p><i>[2013-03-06]</i></p>


<p>
Jonathan suggests to make the new constructors non-explicit and makes some representational improvements.
</p>


<p><i>[2013-09 Chicago]</i></p>

<p>
Move to deferred.
</p>
<p>
This issue has much in common with similar problems with <code>std::function</code> that are being addressed
by the polymorphic allocators proposal currently under evaluation in LEWG.  Defer further discussion on
this topic until the final outcome of that paper and its proposed resolution is known.
</p>

<p><i>[2014-02-20 Re-open Deferred issues as Priority 4]</i></p>


<p><i>[2016-08 Chicago]</i></p>

<p>Fri PM: Send to LEWG  - and this also applies to <code>function</code> in LFTS.</p>

<p><i>[2019-06-03 Jonathan Wakely provides updated wording]</i></p>

<p>Jonathan updates wording post-<a href="lwg-defects.html#2976" title="Dangling uses_allocator specialization for packaged_task (Status: C++20)">2976</a><sup><a href="https://cplusplus.github.io/LWG/issue2976" title="Latest snapshot">(i)</a></sup>
and observes that this resolution conflicts with <a href="lwg-defects.html#3003" title="&lt;future&gt; still has type-erased allocators in promise (Status: Resolved)">3003</a><sup><a href="https://cplusplus.github.io/LWG/issue3003" title="Latest snapshot">(i)</a></sup>.</p>

<p><strong>Previous resolution [SUPERSEDED]:</strong></p>
<blockquote class="note">
<p><i>[This wording is relative to the FDIS.]</i></p>


<ol>
<li><p>Add to 32.10.6 <a href="https://wg21.link/futures.promise">[futures.promise]</a>, class template <code>promise</code> synopsis, 
as indicated:</p>

<blockquote><pre>
namespace std {
  template &lt;class R&gt;
  class promise {
  public:
    promise();
    template &lt;class Allocator&gt;
    promise(allocator_arg_t, const Allocator&amp; a);
    <ins>template &lt;class Allocator&gt;
    promise(allocator_arg_t, const Allocator&amp; a, promise&amp;&amp; rhs) noexcept;</ins>
    promise(promise&amp;&amp; rhs) noexcept;
    promise(const promise&amp; rhs) = delete;
    ~promise();	
    [&hellip;]
  };
  [&hellip;]
}
</pre></blockquote>
</li>

<li><p>Change 32.10.6 <a href="https://wg21.link/futures.promise">[futures.promise]</a> as indicated:</p>

<blockquote><pre>
promise(promise&amp;&amp; rhs) noexcept;
<ins>template &lt;class Allocator&gt;
promise(allocator_arg_t, const Allocator&amp; a, promise&amp;&amp; rhs) noexcept;</ins>
</pre><blockquote>
<p>
-5- <i>Effects</i>: constructs a new <code>promise</code> object and transfers ownership of 
the shared state of <code>rhs</code> (if any) to the newly-constructed object.
<p/>
-6- <i>Postcondition</i>: <code>rhs</code> has no shared state.
<p/>
<ins>-?- [<i>Note</i>: <code>a</code> is not used &mdash; <i>end note</i>]</ins>
</p>
</blockquote></blockquote>

</li>

<li><p>Add to 32.10.10 <a href="https://wg21.link/futures.task">[futures.task]</a>, class template <code>packaged_task</code> synopsis, 
as indicated:</p>

<blockquote><pre>
namespace std {
  template&lt;class&gt; class packaged_task; // <i>undefined</i>

  template&lt;class R, class... ArgTypes&gt;
  class packaged_task&lt;R(ArgTypes...)&gt; {
  public:
    // construction and destruction
    packaged_task() noexcept;
    <ins>template &lt;class Allocator&gt;
      packaged_task(allocator_arg_t, const Allocator&amp; a) noexcept;</ins>
    template &lt;class F&gt;
      explicit 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);
    ~packaged_task();
	
    // no copy
    packaged_task(const packaged_task&amp;) = delete;
    <ins>template&lt;class Allocator&gt;
      packaged_task(allocator_arg_t, const Allocator&amp; a, const packaged_task&amp;) = delete;</ins>
    packaged_task&amp; operator=(const packaged_task&amp;) = delete;
    
    // move support
    packaged_task(packaged_task&amp;&amp; rhs) noexcept;
    <ins>template &lt;class Allocator&gt;
      packaged_task(allocator_arg_t, const Allocator&amp; a, packaged_task&amp;&amp; rhs) noexcept;</ins>
    packaged_task&amp; operator=(packaged_task&amp;&amp; rhs) noexcept;
    void swap(packaged_task&amp; other) noexcept;
    [&hellip;]
  };
  [&hellip;]
}
</pre></blockquote>
</li>

<li><p>Change 32.10.10.2 <a href="https://wg21.link/futures.task.members">[futures.task.members]</a> as indicated:</p>

<blockquote><pre>
packaged_task() noexcept;
<ins>template &lt;class Allocator&gt;
  packaged_task(allocator_arg_t, const Allocator&amp; a) noexcept;</ins>
</pre><blockquote>
<p>
-1- <i>Effects</i>: constructs a <code>packaged_task</code> object with no shared state and no stored task.
<p/>
<ins>-?- [<i>Note</i>: <code>a</code> is not used &mdash; <i>end note</i>]</ins>
</p>
</blockquote></blockquote>
<p>[&hellip;]</p>
<blockquote><pre>
packaged_task(packaged_task&amp;&amp; rhs) noexcept;
<ins>template &lt;class Allocator&gt;
  packaged_task(allocator_arg_t, const Allocator&amp; a, packaged_task&amp;&amp; rhs) noexcept;</ins>
</pre><blockquote>
<p>
-5- <i>Effects</i>: constructs a new <code>packaged_task</code> object and transfers ownership of <code>rhs</code>'s 
shared state to <code>*this</code>, leaving <code>rhs</code> with no shared state. Moves the stored task from <code>rhs</code> 
to <code>*this</code>.
<p/>
-6- <i>Postcondition</i>: <code>rhs</code> has no shared state.
<p/>
<ins>-?- [<i>Note</i>: <code>a</code> is not used &mdash; <i>end note</i>]</ins>
</p>
</blockquote></blockquote>

</li>
</ol>

</blockquote>

<p><i>[2025-06-21 Status changed: LEWG &rarr; Resolved.]</i></p>

Resolved by adoption of <a href="https://wg21.link/P3503R3" title=" Make type-erased allocator use in promise and packaged_task consistent">P3503R3</a> in Sofia.



<p id="res-2095"><b>Proposed resolution:</b></p>
<p><i>[This wording is relative to N4810.]</i></p>


<ol>
<li><p>Add to 32.10.6 <a href="https://wg21.link/futures.promise">[futures.promise]</a>, class template <code>promise</code> synopsis,
as indicated:</p>

<blockquote><pre>
namespace std {
  template &lt;class R&gt;
  class promise {
  public:
    promise();
    template &lt;class Allocator&gt;
      promise(allocator_arg_t, const Allocator&amp; a);
    <ins>template &lt;class Allocator&gt;
      promise(allocator_arg_t, const Allocator&amp; a, promise&amp;&amp; rhs) noexcept;</ins>
    promise(promise&amp;&amp; rhs) noexcept;
    promise(const promise&amp; rhs) = delete;
    ~promise();
    [&hellip;]
  };
  [&hellip;]
}
</pre></blockquote>
</li>

<li><p>Change 32.10.6 <a href="https://wg21.link/futures.promise">[futures.promise]</a> as indicated:</p>

<blockquote><pre>
promise(promise&amp;&amp; rhs) noexcept;
<ins>template &lt;class Allocator&gt;
  promise(allocator_arg_t, const Allocator&amp; a, promise&amp;&amp; rhs) noexcept;</ins>
</pre><blockquote>
<p>
-5- <i>Effects</i>: constructs a new <code>promise</code> object and transfers ownership of
the shared state of <code>rhs</code> (if any) to the newly-constructed object.
<p/>
-6- <i>Postcondition</i>: <code>rhs</code> has no shared state.
<p/>
<ins>-?- [<i>Note</i>: <code>a</code> is not used &mdash; <i>end note</i>]</ins>
</p>
</blockquote></blockquote>

</li>
</ol>





</body>
</html>
