<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html><head>

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

<title>Experimental function etc.</title>

<style type="text/css">
  p {text-align:justify}
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  blockquote.note
  {
   background-color:#E0E0E0;
   padding-left: 15px;
   padding-right: 15px;
   padding-top: 1px;
   padding-bottom: 1px;
  }
</style>
</head><body>
<address style="text-align: left;">
Document number: N4067<br>
Date: 2014-06-20<br>
Author: Daniel Kr&uuml;gler<br>
Project: Programming Language C++, Library Evolution Working Group<br>
Reply-to: <a href="mailto:daniel.kruegler@gmail.com">Daniel Kr&uuml;gler</a>
</address>
<hr>
<h1 style="text-align: center;">Experimental <tt>std::function</tt> etc.</h1>
<h2><a name="Introduction"></a>Introduction</h2>
<p>
This paper provides wording to the effect that it creates independent fundamental-ts types in namespace <tt>std::experimental</tt>
for  <tt>function</tt>, <tt>promise</tt>, and <tt>packaged_task</tt>.
</p>
<h2><a name="Discussion"></a>Discussion</h2>
<p>
Currently, the <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4023.html">fundamental-ts</a>
refers to <tt>std::function</tt> and has applied extensions to that existing C++11 type, which has caused
some significant concerns, which are in detailed described in <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4041.html">N4041</a>.
<p/>
As a consequence of discussing this paper ("Guidelines for the contents of Technical Specifications") and 
performing straw polls within LEWG the following results had been obtained:
</p>
<blockquote>
<p>
<tt>std::function</tt>, etc. changes in <tt>std::experimental</tt>?
<p/>
SF-F-N-A-SA
<p/>
5-8-5-0-1
</p>
</blockquote>
<p>
This proposal attempts to provide wording to realize these effects.
</p>

<h2><a name="Proposed_resolution"></a>Proposed resolution</h2>
<p>
The proposed wording changes refer to <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4023.html">N4023</a>.
</p>
<ol>
<li><p>Add a new entry to Table 1 &mdash; "C++ library headers" as indicated:</p>

<blockquote class="note">
<p>
[<i>Drafting note</i>: Currently no header file <tt>&lt;experimental/future&gt;</tt> exists, but
is needed to isolate the new types <tt>experimental::promise</tt> and <tt>experimental::packaged_task</tt>. 
&mdash; <i>end drafting note</i>]
</p>
</blockquote>

<blockquote>
<table border="1">
<caption>Table 1 &mdash; C++ library headers</caption>

<tr>
<td colspan="1" align="center">
<tt>&hellip;</tt>
</td>
</tr>

<tr>
<td>
<ins><tt>&lt;experimental/future&gt;</tt></ins>
</td>

<tr>
<td colspan="1" align="center">
<tt>&hellip;</tt>
</td>
</tr>

</table>
</blockquote>
</li>

<li><p>Modify Table 2 &mdash; "Significant features in this technical specification" as indicated:</p>

<blockquote class="note">
<p>
[<i>Drafting note</i>: These changes assume that the assigned feature name suffix remains the same. &mdash; <i>end drafting note</i>]
</p>
</blockquote>

<blockquote>
<table border="1">
<caption>Table 2 &mdash; Significant features in this technical specification</caption>
<tr>
<th align="center">Doc.<br/>No.</th>
<th align="center">Title</th>
<th align="center">Primary<br/>Section</th>
<th align="center">Macro Name Suffix</th>
<th align="center">Value</th>
<th align="center">Header</th>
</tr>

<tr>
<td colspan="6" align="center">
<tt>&hellip;</tt>
</td>
</tr>

<tr>
<td>
N3916
</td>
<td>
Type-erased allocator<br/>for <tt>std::function</tt>
</td>
<td>
<del>2.3 [mods.func.wrap]</del><br/>
<ins>4.2 [exp.func.wrap.func]</ins>
</td>
<td>
<tt>function_erased_allocator</tt>
</td>
<td>
<tt>201402</tt>
</td>
<td>
<del><tt>&lt;functional&gt;</tt></del><br/>
<ins><tt>&lt;experimental/functional&gt;</tt></ins>
</td>
</tr>

<tr>
<td colspan="6" align="center">
<tt>&hellip;</tt>
</td>
</tr>

<tr>
<td>
N3916
</td>
<td>
Type-erased allocator<br/>for <tt>std::promise</tt>
</td>
<td>
<del>2.6 [mods.futures.promise]</del><br/>
<ins>?.? [exp.futures.promise]</ins>
</td>
<td>
<tt>promise_erased_allocator</tt>
</td>
<td>
<tt>201402</tt>
</td>
<td>
<del><tt>&lt;future&gt;</tt></del><br/>
<ins><tt>&lt;experimental/future&gt;</tt></ins>
</td>
</tr>

<tr>
<td>
N3916
</td>
<td>
Type-erased allocator<br/>for <tt>std::packaged_task</tt>
</td>
<td>
<del>2.7 [mods.futures.task]</del><br/>
<ins>?.? [exp.futures.task]</ins>
</td>
<td>
<tt>packaged_task_erased_allocator</tt>
</td>
<td>
<tt>201402</tt>
</td>
<td>
<del><tt>&lt;future&gt;</tt></del><br/>
<ins><tt>&lt;experimental/future&gt;</tt></ins>
</td>
</tr>

<tr>
<td colspan="6" align="center">
<tt>&hellip;</tt>
</td>
</tr>

</table>
</blockquote>
</li>

<li><p>Remove the existing sub-clause 2.3 [mods.func.wrap] in its entirety:</p>

<p>
<del><b>2.3 Additions to <tt>std::function</tt> [mods.func.wrap]</b></del>
</p>
<blockquote>
<p>
<del>-1- [&hellip;]</del>
<p/>
<del>[&hellip;]</del>
<p/>
<del>-22- <i>Effects</i>: Interchanges the targets of <tt>*this</tt> and <tt>other</tt>.</del>
</p>
</blockquote>
</li>

<li><p>Remove the existing sub-clause 2.6 [mods.futures.promise] in its entirety:</p>

<p>
<del><b>2.6 Additions to <tt>std::promise</tt> [mods.futures.promise]</b></del>
</p>
<blockquote>
<p>
<del>-1- [&hellip;]</del>
<p/>
<del>-2- and the following paragraph is inserted [&hellip;]</del>
</p>
</blockquote>
</li>

<li><p>Remove the existing sub-clause 2.7 [mods.futures.task] in its entirety:</p>

<p>
<del><b>2.7 Additions to <tt>std::packaged_task</tt> [mods.futures.task]</b></del>
</p>
<blockquote>
<p>
<del>-1- [&hellip;]</del>
<p/>
<del>-2- and the following paragraph is inserted [&hellip;]</del>
</p>
</blockquote>
</li>

<li><p>Change header <tt>&lt;experimental/functional&gt;</tt> synopsis, 4.1 [header.functional.synop], as indicated:</p>

<blockquote class="note">
<p>
[<i>Drafting note</i>: The following header synopsis fixes the missing <tt>noexcept</tt> specifications of
the comparison functions as recently resolved by <a href="http://cplusplus.github.io/LWG/lwg-active.html#2401">LWG 2401</a>
yet. We consider this change <em>editorial</em> at this point, because the two different declarations were already in conflict
and this change does not have impact on the actual prototype specifications, which will have the same specifiers as in C++14. 
&mdash; <i>end drafting note</i>]
</p>
</blockquote>

<blockquote>
<pre>
#include &lt;functional&gt;

namespace std {
namespace experimental {
inline namespace fundamentals_v1 {
[&hellip;]
<ins><i>// 4.2 Class template function:</i>
template&lt;class&gt; class function; <i>// undefined</i>
template&lt;class R, class... ArgTypes&gt; class function&lt;R(ArgTypes...)&gt;;

template&lt;class R, class... ArgTypes&gt;
void swap(function&lt;R(ArgTypes...)&gt;&amp;, function&lt;R(ArgTypes...)&gt;&amp;);

template&lt;class R, class... ArgTypes&gt;
bool operator==(const function&lt;R(ArgTypes...)&gt;&amp;, nullptr_t) noexcept;
template&lt;class R, class... ArgTypes&gt;
bool operator==(nullptr_t, const function&lt;R(ArgTypes...)&gt;&amp;) noexcept;
template&lt;class R, class... ArgTypes&gt;
bool operator!=(const function&lt;R(ArgTypes...)&gt;&amp;, nullptr_t) noexcept;
template&lt;class R, class... ArgTypes&gt;
bool operator!=(nullptr_t, const function&lt;R(ArgTypes...)&gt;&amp;) noexcept;</ins>
[&hellip;]
}
}

<ins>template&lt;class R, class... ArgTypes, class Alloc&gt;
struct uses_allocator&lt;experimental::function&lt;R(ArgTypes...)&gt;, Alloc&gt;;</ins>

}
</pre>
</blockquote>
</li>

<li><p>Between 4.1 [header.functional.synop] and 4.2 [func.searchers] insert
the following new sub-clause as indicated:</p>

<p>
<ins>4.2 Class template <tt>function</tt> [exp.func.wrap.func]</ins>
</p>

<blockquote class="note">
<p>
[<i>Drafting note</i>: The following class template synopsis fixes the missing <tt>noexcept</tt> specification of
the <tt>nullptr_t</tt> assignment operator as recently resolved by <a href="http://cplusplus.github.io/LWG/lwg-active.html#2401">LWG 2401</a>.
We consider this change as <em>editorial</em>, because the fundamental-ts specification refers otherwise to a non-existing
declaration in C++14. &mdash; <i>end drafting note</i>]
</p>
</blockquote>

<blockquote>
<p>
<ins>The specification of all declarations within this sub-clause 4.2 [exp.func.wrap.func] 
and its sub-clauses are the same as the corresponding declarations, as specified in C++14 &sect;20.9.11.2, 
unless explicitly specified otherwise. [<i>Note</i>: <tt>std::experimental::function</tt> uses 
<tt>std::bad_function_call</tt>, there is no additional type <tt>std::experimental::bad_function_call</tt> &mdash; <i>end note</i>].
</ins>
</p>
<blockquote>
<pre>
<ins>namespace std {
  namespace experimental {
  inline namespace fundamentals_v1 {

    template&lt;class&gt; class function; <i>// undefined</i>
    
    template&lt;class R, class... ArgTypes&gt;
    class function&lt;R(ArgTypes...)&gt; {
    public:
      typedef R result_type;
      typedef T1 argument_type;
      typedef T1 first_argument_type;
      typedef T2 second_argument_type;
	  
      typedef erased_type allocator_type;
    
      function() noexcept;
      function(nullptr_t) noexcept;
      function(const function&amp;);
      function(function&amp;&amp;);
      template&lt;class F&gt; function(F);
      template&lt;class A&gt; function(allocator_arg_t, const A&amp;) noexcept;
      template&lt;class A&gt; function(allocator_arg_t, const A&amp;,
        nullptr_t) noexcept;
      template&lt;class A&gt; function(allocator_arg_t, const A&amp;,
        const function&amp;);
      template&lt;class A&gt; function(allocator_arg_t, const A&amp;,
        function&amp;&amp;);
      template&lt;class F, class A&gt; function(allocator_arg_t, const A&amp;, F);
    
      function&amp; operator=(const function&amp;);
      function&amp; operator=(function&amp;&amp;);
      function&amp; operator=(nullptr_t) noexcept;
      template&lt;class F&gt; function&amp; operator=(F&amp;&amp;);
      template&lt;class F&gt; function&amp; operator=(reference_wrapper&lt;F&gt;);
	  
      ~function();
	  
      void swap(function&amp;);
      template&lt;class F, class A&gt; void assign(F&amp;&amp;, const A&amp;);
    
      explicit operator bool() const noexcept;
    
      R operator()(ArgTypes...) const;
    
      const type_info&amp; target_type() const noexcept;
      template&lt;class T&gt; T* target() noexcept;
      template&lt;class T&gt; const T* target() const noexcept;

      pmr::memory_resource* get_memory_resource();
    };
    
    template &lt;class R, class... ArgTypes&gt;
    bool operator==(const function&lt;R(ArgTypes...)&gt;&amp;, nullptr_t) noexcept;
    template &lt;class R, class... ArgTypes&gt;
    bool operator==(nullptr_t, const function&lt;R(ArgTypes...)&gt;&amp;) noexcept;
    
    template &lt;class R, class... ArgTypes&gt;
    bool operator!=(const function&lt;R(ArgTypes...)&gt;&amp;, nullptr_t) noexcept;
    template &lt;class R, class... ArgTypes&gt;
    bool operator!=(nullptr_t, const function&lt;R(ArgTypes...)&gt;&amp;) noexcept;
    
    template &lt;class R, class... ArgTypes&gt;
    void swap(function&lt;R(ArgTypes...)&gt;&amp;, function&lt;R(ArgTypes...)&gt;&amp;);

  } <i>// namespace fundamentals_v1</i>
  } <i>// namespace experimental</i>

  template &lt;class R, class... ArgTypes, class Alloc&gt;
  struct uses_allocator&lt;experimental::function&lt;R(ArgTypes...)&gt;, Alloc&gt;
    : true_type { };

} <i>// namespace std</i></ins>
</pre>
</blockquote>
</blockquote>
</li>

<li><p>Add the following new sub-clause as a children of 4.2 [exp.func.wrap.func] including its first paragraph, 
that replaces the corresponding specification provided by paragraph 1 of C++14 &sect;20.9.11.2.1. Then add the following
changed member specifications:</p>
<p>
<ins><b>4.2.1 <tt>function</tt> construct/copy/destroy</b> [exp.func.wrap.func.con]</ins>
</p>

<blockquote class="note">
<p>
[<i>Drafting note</i>: The following first paragraph has been slightly editorially improved to (a) make the difference
between <tt>std::function</tt> and <tt>std::experimental::function</tt> clearer (which seems necessary due to the 
"including" wording that can be parsed in two different ways) and (b) to make intended normative wording clearer, that had
been put into parenthesis before, by simply removing these parenthesis) &mdash; <i>end drafting note</i>]
</p>
</blockquote>

<blockquote>
<p>
<ins>-?- When a <tt>function</tt> constructor that takes a first argument of type <tt>allocator_arg_t</tt> is invoked, the second argument 
is treated as a <em>type-erased allocator</em> (8.3 [memory.type.erased.allocator]). If the constructor moves or makes a copy 
of a function object (C++14 &sect;20.9), including an instance of the <tt>experimental::function</tt> class template, then that move or 
copy is performed by <em>using-allocator construction</em> with allocator <tt>get_memory_resource()</tt>.
</ins>
</p>

<pre>
<ins>function&amp; operator=(const function&amp; f);</ins>
</pre>
<blockquote>
<p>
<ins>-?- <i>Effects</i>: <tt>function(allocator_arg, get_memory_resource(), f).swap(*this);</tt></ins>
<p/>
<ins>-?- <i>Returns</i>: <tt>*this</tt></ins> 
</p>
</blockquote>

<pre>
<ins>function&amp; operator=(function&amp;&amp; f);</ins>
</pre>
<blockquote>
<p>
<ins>-?- <i>Effects</i>: <tt>function(allocator_arg, get_memory_resource(), std::move(f)).swap(*this);</tt></ins>
<p/>
<ins>-?- <i>Returns</i>: <tt>*this</tt></ins> 
</p>
</blockquote>

<blockquote class="note">
<p>
[<i>Drafting note</i>: The following <i>Effects</i> element has been fixed and syncs the wording "<tt>*this != NULL</tt>" 
with the C++14 working draft replacing it with "<tt>*this != nullptr</tt>" &mdash; <i>end drafting note</i>]
</p>
</blockquote>

<pre>
<ins>function&amp; operator=(nullptr_t) noexcept;</ins>
</pre>
<blockquote>
<p>
<ins>-?- <i>Effects</i>: If <tt>*this != nullptr</tt>, destroys the target of <tt>this</tt>.</ins>
<p/>
<ins>-?- <i>Postconditions</i>: <tt>!(*this)</tt>.
<p/>
<ins>-?- <i>Returns</i>: <tt>*this</tt></ins> 
</p>
</blockquote>

<pre>
<ins>template&lt;class F&gt; function&amp; operator=(F&amp;&amp; f);</ins>
</pre>
<blockquote>
<p>
<ins>-?- <i>Effects</i>: <tt>function(allocator_arg, get_memory_resource(), std::forward&lt;F&gt;(f)).swap(*this);</tt></ins>
<p/>
<ins>-?- <i>Returns</i>: <tt>*this</tt></ins> 
</p>
</blockquote>

<pre>
<ins>template&lt;class F&gt; function&amp; operator=(reference_wrapper&lt;F&gt; f);</ins>
</pre>
<blockquote>
<p>
<ins>-?- <i>Effects</i>: <tt>function(allocator_arg, get_memory_resource(), f).swap(*this);</tt></ins>
<p/>
<ins>-?- <i>Returns</i>: <tt>*this</tt></ins> 
</p>
</blockquote>

</blockquote>
</li>

<li><p>Add the following new sub-clause as a children of 4.2 [exp.func.wrap.func] and add the following
changed member specifications:</p>
<p>
<ins><b>4.2.2 <tt>function</tt> modifiers</b> [exp.func.wrap.func.mod]</ins>
</p>
<blockquote>
<pre>
<ins>void swap(function&amp; other);</ins>
</pre>
<blockquote>

<blockquote class="note">
<p>
[<i>Drafting note</i>: The previous <i>Preconditions</i> element has been replaced by a <i>Requires</i> element,
see <a href="http://cplusplus.github.io/LWG/lwg-active.html#2395">LWG 2395</a> &mdash; <i>end drafting note</i>]
</p>
</blockquote>

<p>
<ins>-?- <i>Requires</i>: <tt>this-&gt;get_memory_resource() == other-&gt;get_memory_resource()</tt>.</ins>
<p/>
<ins>-?- <i>Effects</i>: Interchanges the targets of <tt>*this</tt> and <tt>other</tt>.</ins>
</p>
</blockquote>
</blockquote>
</li>

<li><p>Following 8 [memory], insert a new Clause [exp.future] and sub-clause [header.exp.future.synop] as indicated:</p>

<p>
<ins><b>Futures</b> [exp.future]</ins>
<p/>
<ins>Header <tt>&lt;experimental/future&gt;</tt> synopsis [header.exp.future.synop]</ins>
</p>

<blockquote class="note">
<p>
[<i>Drafting note</i>: An additional editorial fix is applied in the declaration of
<tt>swap</tt> for <tt>packaged_task</tt> &mdash; <i>end drafting note</i>]
</p>
</blockquote>

<blockquote><pre>
<ins>#include &lt;future&gt;

namespace std {
  namespace experimental {
  inline namespace fundamentals_v1 {

    template &lt;class R&gt; class promise;
    template &lt;class R&gt; class promise&lt;R&amp;&gt;;
    template &lt;&gt; class promise&lt;void&gt;;

    template &lt;class R&gt;
    void swap(promise&lt;R&gt;&amp; x, promise&lt;R&gt;&amp; y) noexcept;

    template &lt;class&gt; class packaged_task; // undefined
    template &lt;class R, class... ArgTypes&gt;
    class packaged_task&lt;R(ArgTypes...)&gt;;

    template &lt;class R, class... ArgTypes&gt;
    void swap(packaged_task&lt;R(ArgTypes...)&gt;&amp;, packaged_task&lt;R(ArgTypes...)&gt;&amp;) noexcept;
	
  } <i>// namespace fundamentals_v1</i>
  } <i>// namespace experimental</i>

  template &lt;class R, class Alloc&gt;
  struct uses_allocator&lt;experimental::promise&lt;R&gt;, Alloc&gt;;

  template &lt;class R, class Alloc&gt;
  struct uses_allocator&lt;experimental::packaged_task&lt;R&gt;, Alloc&gt;;  

} <i>// namespace std</i></ins>
</pre></blockquote>
</li>

<li><p>As children of the new Clause [exp.future], insert a new sub-clause [exp.futures.promise] as indicated:</p>

<p>
<ins><b>?.? Class template <tt>promise</tt></b> [exp.futures.promise]</ins>
</p>
<blockquote>
<p>
<ins>The specification of all declarations within this sub-clause [exp.futures.promise] 
and its sub-clauses are the same as the corresponding declarations, as specified in C++14 &sect;30.6.5, 
unless explicitly specified otherwise. &mdash; <i>end note</i>].
</ins>
</p>
<blockquote>
<pre>
<ins>namespace std {
  namespace experimental {
  inline namespace fundamentals_v1 {

    template &lt;class R&gt;
    class promise {
    public:
      typedef erased_type allocator_type;

      promise();
      template &lt;class Allocator&gt;
      promise(allocator_arg_t, const Allocator&amp; a);
      promise(promise&amp;&amp; rhs) noexcept;
      promise(const promise&amp; rhs) = delete;
      ~promise();
	 
      promise&amp; operator=(promise&amp;&amp; rhs) noexcept;
      promise&amp; operator=(const promise&amp; rhs) = delete;
      void swap(promise&amp; other) noexcept;

      future&lt;R&gt; get_future();
	  
      void set_value(<em>see below</em>);
      void set_exception(exception_ptr p);
	  
      void set_value_at_thread_exit(const R&amp; r);
      void set_value_at_thread_exit(<em>see below</em>);
      void set_exception_at_thread_exit(exception_ptr p);

      pmr::memory_resource* get_memory_resource();	
    };
    
    template &lt;class R&gt;
    void swap(promise&lt;R&gt;&amp; x, promise&lt;R&gt;&amp; y) noexcept;

  } <i>// namespace fundamentals_v1</i>
  } <i>// namespace experimental</i>

  template &lt;class R, class Alloc&gt;
  struct uses_allocator&lt;experimental::promise&lt;R&gt;, Alloc&gt;;

} <i>// namespace std</i></ins>
</pre>
<blockquote>
<p>
<ins>When a <tt>promise</tt> constructor that takes a first argument of type <tt>allocator_arg_t</tt> is invoked, 
the second argument is treated as a type-erased allocator (8.3).</ins>
</p>
</blockquote>
</blockquote>
</blockquote>
</li>

<li><p>As children of the new Clause [exp.future], insert a new sub-clause [exp.futures.task] as indicated:</p>

<p>
<ins><b>?.? Class template <tt>packaged_task</tt></b> [exp.futures.task]</ins>
</p>
<blockquote>
<p>
<ins>The specification of all declarations within this sub-clause [exp.futures.task] 
and its sub-clauses are the same as the corresponding declarations, as specified in C++14 &sect;30.6.9, 
unless explicitly specified otherwise. &mdash; <i>end note</i>].
</ins>
</p>

<blockquote class="note">
<p>
[<i>Drafting note</i>: Contrary to C++14 the repeated declaration of the primary
<tt>packaged_task</tt> seems unnecessary here, because the same thing is already said in
the header synopsis &mdash; <i>end drafting note</i>]
</p>
</blockquote>

<blockquote>
<pre>
<ins>namespace std {
  namespace experimental {
  inline namespace fundamentals_v1 {

    template &lt;class R, class... ArgTypes&gt;
    class packaged_task&lt;R(ArgTypes...)&gt; {
    public:
      typedef erased_type allocator_type;

      packaged_task() noexcept;
      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();
      	 
      packaged_task(const packaged_task&amp;) = delete;
      packaged_task&amp; operator=(const packaged_task&amp;) = delete;
      
      packaged_task(packaged_task&amp;&amp; rhs) noexcept;
      packaged_task&amp; operator=(packaged_task&amp;&amp; rhs) noexcept;
      void swap(packaged_task&amp; other) noexcept;
      	  
      bool valid() const noexcept;
      	  
      future&lt;R&gt; get_future();
      
      void operator()(ArgTypes... );
      void make_ready_at_thread_exit(ArgTypes...);
      
      void reset();
	  
      pmr::memory_resource* get_memory_resource();	
    };
    
    template &lt;class R, class... ArgTypes&gt;
    void swap(packaged_task&lt;R(ArgTypes...)&gt;&amp;, packaged_task&lt;R(ArgTypes...)&gt;&amp;) noexcept;

  } <i>// namespace fundamentals_v1</i>
  } <i>// namespace experimental</i>

  template &lt;class R, class Alloc&gt;
  struct uses_allocator&lt;experimental::packaged_task&lt;R&gt;, Alloc&gt;;

} <i>// namespace std</i></ins>
</pre>
<blockquote>
<p>
<ins>When a <tt>packaged_task</tt> constructor that takes a first argument of type <tt>allocator_arg_t</tt> is invoked, 
the second argument is treated as a type-erased allocator (8.3).</ins>
</p>
</blockquote>
</blockquote>
</li>

</ol>

</body></html>