<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head>
<meta http-equiv="content-type" content="text/html; charset=windows-1252">
  <style type="text/css">

.comment { color: #999999; font-style: italic; }
.pre { color: #000099; }
.string { color: #009900; }
.char { color: #009900; }
.float { color: #996600; }
.int { color: #999900; }
.bool { color: #000000; font-weight: bold; }
.type { color: #FF6633; }
.flow { color: #FF0000; }
.keyword { color: #990000; }
.operator { color: #663300; font-weight: bold; }
.operator { color: #663300; font-weight: bold; }
pre.code {
    border: 2px solid #666;
    background-color: #F4F4F4;
    padding-left: 10px;
    padding-top: 0px;
}
code {
    border: 2px solid #d0d0d0;
    background-color: LightYellow;
    padding: 2px;
    padding-left: 10px;
    display:table;
    white-space:pre;
    margin:2px;
    margin-bottom:10px;
}
dt {
    font-weight: bold;
}
.ins {
    background-color:#A0FFA0;
}
.del {
    background-color:#FFA0A0;
    text-decoration:line-through
}
.TODO {
    background-color: LightYellow;
    color: red;
}
	  
</style>

<title>Toward a resolution of US7 and US14: Integrating template
deduction for class templates into the standard library</title>
</head>

<body>
<p>Document number: P00433R0 <br>
Date: 2016-10-16<br>
Reply-To:<br>
&nbsp;&nbsp;&nbsp;Mike Spertus, Symantec (<a href="mailto:mike_spertus@symantec.com">mike_spertus@symantec.com</a>)<br>
&nbsp;&nbsp;&nbsp;Walter E. Brown<a href="mailto:webrown.cpp@gmail.com"> (webrown.cpp@gmail.com</a>)<br>
Audience: {Library Evolution, Library, Core} Working Group
</p>

<h1>Toward a resolution of US7 and US14: Integrating template
deduction for class templates into the standard library</h1>
<h2>Introduction</h2>
<p>
National body comments US7 and US14 request analysis of the standard library 
to determine what changes might be desirable
in light of the C++17 adoption of <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0091r3.html">P0091R3</a>
(Template argument deduction for class templates (rev. 6)).
In this paper, we perform such an analysis and recommend wording changes
for clauses 17 through 23 and also propose some refinements to the
wording of P0091R3. If the committee agrees with the approach taken here,
    we will perform a similar analysis for the remaining library clauses.
</p>
<h2>Core language assumptions</h2>
<p>There are some areas where the wording around template deduction for constructors
	in the draft standard seems unclear. In this paper,
	we make the following assumptions about
	the core language.</p>
<ul><li>Overload candidates: If there is an explicit and implicit deduction
	guide with the same signature, then only the explicit deduction guides are considered.</li>
	<li>Implicit conversion functions: An implicit deduction guide may be
	used as an implicit conversion function only if its constructor is
	not explicit. An explicit deduction guide must declare if it cannot be used
	as an explicit conversion function.</li></ul>
<p>
	We make these precise in the following wording changes:</p>
<p>Change &sect;13.3.18 [class.template.deduction] as follows:</p>
<blockquote><b>13.3.1.8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Class Template Deduction&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[class.template.deduction]</b><br/>
The overload set consists of:
<ul>
    <li> <span class="ins">For each <em>deduction-guide</em>, a function or function template with the following properties is a candidate:</span>
    <ul>
        <li><span class="ins">The template parameters, if any, and function parameters are those of the <em>deduction-guide</em>.</span></li>
        <li><span class="ins">The return type is the <em>simple-template-id</em> of the <em>deduction-guide</em>.</span></li>
		<li><span class="ins">If the constructor is not explicit, the function shall not be a candidate for a non-explicit conversion
		function.</span></li></ul>
    </li>
	<li> For each constructor of the class template designated by
   the <em>template-name</em>, a function template with the following properties
     is a candidate <span class="ins">unless a function with the same signature
		derived from a <em>deduction-guide</em> was added to the candidate list
	 as described above</span>:
     <ul>
         <li>The template parameters are the template parameters of the class template followed by the template parameters (including default template arguments) of the constructor, if any.</li>
         <li>The types of the function parameters <span class="ins">(including default arguments)</span> are those of the constructor.</li>
         <li>The return type is the class template specialization designated by the <em>template-name</em> and template arguments corresponding to the template parameters obtained from the class template.</li>
		<li>If the <em>deduction-guide</em> was introduced with the keyword <tt>explicit</tt>, the function shall not be a candidate for a non-explicit conversion
		function.</li></ul>
</li>
	<li><span class="del"> For each <em>deduction-guide</em>, a function or function template with the following properties is a candidate:</span>
    <ul>
        <li><span class="del">The template parameters, if any, and function parameters are those of the <em>deduction-guide</em>.</span></li>
		<li><span class="del">The return type is the <em>simple-template-id</em> of the <em>deduction-guide</em>.</span></li></ul>
    </li>
    </ul></span></blockquote>
Modify the end of &sect;14.9p1 [temp.deduct.guide] as follows:
<blockquote><em>deduction-guide:</em><br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="ins"><tt>explicit</tt><sub><em>opt</em></sub></span>
	<em>template-name </em>	<tt>(</tt> <em>parameter-declaration-clause</em> <tt>) -&gt;</tt>
	 <em>simple-template-id</em> <tt>;</tt></blockquote>
<h1>Library changes</h1>
The remainder of this paper walks through clauses 17 through 23 of the standard and proposes wording changes to take advantage of template deduction for class templates. 
Even where no wording changes are required, we often call out classes that benefit from implicitly
generated deduction guides as library vendors may choose to add explicit deduction guides
according to the &ldquo;as-if&rdquo; rule. See &sect;21 below for an example of this.
<h2>&sect;17 [library]</h2>
    This clause requires no changes
    because it specifies only C libraries and so no class templates are involved.

<h2>&sect;18 [language.support]</h2>
    No changes are required to &sect;18 [language.support].

    <p>
    <b>Rationale:</b> All of the headers in &sect;18 are listed in
    &ldquo;Table 30 &mdash; Language support library summary&rdquo; in &sect;18.1
    [support.general]:
    </p>

    <table border="1"><tbody><tr><th></th><th>Subclause</th><th>Header(s)</th></tr>
    <tr><td>18.2</td><td>Common definitions</td><td><tt>&lt;cstddef&gt;</tt></td></tr>
    <tr><td>18.3</td><td>Implementation properties</td><td><tt>&lt;limits&gt;<br>&lt;climits&gt;<br>&lt;cfloat&gt;</tt></td></tr><tr><td>18.4</td><td>Integer types</td><td><tt>&lt;cstdint&gt;</tt></td></tr>
    <tr><td>18.5</td><td>Start and termination</td><td><tt>&lt;cstdlib&gt;</tt></td></tr>
    <tr><td>18.6</td><td>Dynamic memory management</td><td><tt>&lt;new&gt;</tt></td></tr>
    <tr><td>18.7</td><td>Type identification</td><td><tt>&lt;typeinfo&gt;</tt></td></tr>
    <tr><td>18.8</td><td>Exception handling</td><td><tt>&lt;exception&gt;</tt></td></tr>
    <tr><td>18.9</td><td>Initializer lists</td><td><tt>&lt;initializer_list&gt;</tt></td></tr>
    <tr><td>18.10</td><td>Other runtime support</td><td><tt>&lt;csignal&gt;<br>&lt;csetjmps&gt;<br>&lt;cstdalign&gt;<br>&lt;cstdarg&gt;<br>&lt;cstdbool&gt;<br>&lt;cstdlib&gt;</tt></td></tr>
    </tbody></table>

    <h3><tt>&lt;limits&gt;</tt></h3>
    The only class template in <tt>&lt;limits&gt;</tt>
    is <tt>numeric_limits</tt>.
    It has no non-default constructors (and only static members),
    so no changes are needed.

    <h3><tt>&lt;intializer_list&gt;</tt></h3>
    The &lt;initializer_list&gt; class template
    has only a default constructor
    and “magic” construction
    (from braced initializer lists)
    that already does template constructor deduction,
    so no changes are required.

    <h3>Remaining headers in this clause</h3>
    None of the <tt>&lt;c&hellip;&gt;</tt> headers or <tt>&lt;new&gt;</tt>,
    <tt>&lt;typeinfo&gt;</tt>, or <tt>&lt;exception&gt;</tt> define class templates,
    so they are unaffected by template constructor deduction.

<h2>&sect;19 [diagnostics]</h2>
    No changes are required to &sect;19 [diagnostics].<p>

    <b>Rationale:</b> All of the headers in &sect;19 are listed in
    &ldquo;Table 31 &mdash; Diagnostics library summary&rdquo; in &sect;19.1:
    </p><table border="1"><tbody><tr><th></th><th>Subclause</th><th>Header(s)</th></tr>
    <tr><td>19.2</td><td>Exception classes</td><td><tt>&lt;stdexcept&gt;</tt></td></tr>
    <tr><td>19.3</td><td>Assertions</td><td><tt>&lt;cassert&gt;</tt></td></tr>
    <tr><td>19.4</td><td>Error numbers</td><td><tt>&lt;cerrno&gt;</tt></td></tr>
    <tr><td>19.5</td><td>System error support</td><td><tt>&lt;system_error&gt;</tt></td></tr>
    </tbody></table>

    <h3><tt>&lt;stdexcept&gt;</tt>,
    <tt>&lt;cassert&gt;</tt>,
    <tt>&lt;cerrno&gt;</tt></h3>
    <p>
    None of these define any class templates,
    so they are unaffected by template constructor deduction.
    </p>

    <h3><tt>&lt;system_error&gt;</tt></h3>
    <p>
    This header defines the class templates <tt>is_error_code_enum</tt>,
    <tt>is_error_condition_enum</tt>,
    and specializations of <tt>std::hash</tt>,
    all of which have  only default constructors.
    </p>

<h2>&sect;20 [utilities]</h2>
    No changes are required to &sect;19 [diagnostics].<p>

    <b>Rationale:</b> All of the headers in &sect;20 are listed in
    &ldquo;Table 32 &mdash; General utilities library summary&rdquo; in &sect;20.1:
    </p><table border="1"><tbody><tr><th></th><th>Subclause</th><th>Header(s)</th></tr>
    <tr><td>20.2</td><td>Utilities components</td><td><tt>&lt;utility&gt;</tt></td></tr>
    <tr><td>20.3</td><td>Compile-time integer sequences</td><td><tt>&lt;utility&gt;</tt></td></tr>
    <tr><td>20.4</td><td>Pairs</td><td><tt>&lt;utility&gt;</tt></td></tr>
    <tr><td>20.5</td><td>Tuples</td><td><tt>&lt;tuple&gt;</tt></td></tr>
    <tr><td>20.6</td><td>Optional objects</td><td><tt>&lt;optional&gt;</tt></td></tr>
    <tr><td>20.7</td><td>Variants</td><td><tt>&lt;variant&gt;</tt></td></tr>
    <tr><td>20.8</td><td>Storage for any type</td><td><tt>&lt;any&gt;</tt></td></tr>
    <tr><td>20.9</td><td>Fixed-size sequences of bits</td><td><tt>&lt;bitset&gt;</tt></td></tr>
    <tr><td>20.10</td><td>Memory</td><td><tt>&lt;memory&gt;<br>&lt;cstdlib&gt;</tt></td></tr>
    <tr><td>20.11</td><td>Smart pointers</td><td><tt>&lt;memory&gt;</tt></td></tr>
    <tr><td>20.12</td><td>Memory resources</td><td><tt>&lt;memory_resource&gt;</tt></td></tr>
    <tr><td>20.13</td><td>Scoped allocators</td><td><tt>&lt;scoped_allocator&gt;</tt></td></tr>
    <tr><td>20.14</td><td>Function objects</td><td><tt>&lt;functional&gt;</tt></td></tr>
    <tr><td>20.15</td><td>Type traits</td><td><tt>&lt;type_traits&gt;</tt></td></tr>
    <tr><td>20.16</td><td>Compile-time rational arithmetic</td><td><tt>&lt;ratio&gt;</tt></td></tr>
    <tr><td>20.17</td><td>Time utilities</td><td><tt>&lt;chrono&gt;<br>&lt;ctime&gt;</tt></td></tr>
    <tr><td>20.18</td><td>Type indexes</td><td><tt>&lt;typeindex&gt;</tt></td></tr>
    <tr><td>20.19</td><td>Execution policies</td><td><tt>&lt;execution&gt;</tt></td></tr>
    </tbody></table>

<h3>&sect;20.2 [utility]</h3>
    No changes are required in this subclause as it specifies no class templates.


<h3>&sect;20.3 [intseq]</h3>
    No changes are required in &sect;20.3.
    Although <tt>integer_sequence</tt> is a class template,
    it has no non-default constructors.
    Interestingly, while the name <tt>make_integer_sequence</tt>
    &ldquo;looks like&rdquo; a make function,
    which is what the paper is trying to replace,
    it is actually a type and therefore a different beast altogether.

<h3>&sect;20.4 [pairs]</h3>
    In this case,
    we would like to avoid unexpected behavior
    by having the pair constructor behave in the same manner
    that was deemed desirable for <tt>make_pair</tt>.
    To accomplish that,
    make the following change
    to the definition
    of <tt>std::pair</tt> in &sect;20.4.2 [pairs.pair]:

    <blockquote><pre>    void swap(pair&amp; p) noexcept(<em>see below</em>);
    };

<span class="ins">  template&lt;class T1, class T2&gt;
  pair(T1&amp;&amp;, T2&amp;&amp;) -&gt; pair&lt;<em>see below</em>&gt;;</span>
}</pre></blockquote>

	At the end of &sect;20.4.2 [pairs.pair], add the following:
<blockquote><pre><span class="ins">template &lt;class T1, class T2&gt;
  pair(T1&amp;&amp;, T2&amp;&amp;) -&gt; pair&lt;V1, V2&gt;;</span></pre>
<blockquote><span class="ins"><em>Remarks: </em><tt>V1</tt> and <tt>V2</tt> are determined
	as follows: Let <tt>Ui</tt> be <tt>decay_t&lt;Ti&gt;</tt> for each <tt>Ti</tt>.
Then each <tt>Vi</tt> is <tt>X&amp;</tt> if <tt>Ui</tt> equals <tt>reference_wrapper&lt;X&gt;</tt>,
	otherwise <tt>Vi</tt> is <tt>Ui</tt>.</span></blockquote></blockquote>

In addition, change &sect;20.4.3p9 [pairs.spec] as follows:
<blockquote><pre>template &lt;class T1, class T2&gt;
  constexpr <span class="del">pair&lt;V1, V2&gt;</span><span class="ins">decltype(pair(declval&lt;T1&amp;&amp;&gt;(), declval&lt;T2&amp;&amp;&gt;())</span> make_pair(T1&amp;&amp; x, T2&amp;&amp; y);</pre>
<blockquote><em>Returns: </em><tt>pair<span class="del">&lt;V1, V2&gt;</span>(std::forward&lt;T1&gt;(x), std::forward&lt;T2&gt;(y));</tt><br><span class="del">where <tt>V1</tt> and <tt>V2</tt> are determined
	as follows: Let <tt>Ui</tt> be <tt>decay_t&lt;Ti&gt;</tt> for each <tt>Ti</tt>.
Then each <tt>Vi</tt> is <tt>X&amp;</tt> if <tt>Ui</tt> equals <tt>reference_wrapper&lt;X&gt;</tt>,
	otherwise <tt>Vi</tt> is <tt>Ui</tt>.</span><br>
[ <em>Example: </em> In place of:
	<blockquote><tt>return pair&lt;int, double&gt;(5, 3.1415926); <span class="comment">// explicit types</span></tt></blockquote>
	a C++ program may <span class="del">contain</span><span class="ins">provide either</span>:<blockquote><tt>return make_pair(5, 3.1415926); <span class="comment">// types are deduced</span></tt></blockquote> <span class="ins">or</span>
<blockquote><span class="ins"><tt>return pair(5, 3.1415926); <span class="comment">// types implicitly deduced by constructor</span></tt></span></blockquote></blockquote></blockquote>
<b>Note:</b> Although the explicit deduction guide obviates the need for <tt>make_pair</tt>, we do not propose deprecating
<tt>make_pair</tt> at this time.<p>
<h3>&sect;20.5 [tuple]</h3>
<tt>tuple</tt> is handled similary to <tt>pair</tt>.    To accomplish that,
    make the following change
    to the definition
    of <tt>std::tuple</tt> in &sect;20.5.2 [tuple.tuple]:

    <blockquote><pre>    void swap(tuple&amp;) noexcept(<em>see below</em>);
    };

<span class="ins">  template&lt;class... UTypes&gt;
  tuple(UTypes...) -&gt; tuple&lt;<em>see below</em>&gt;;</span>
}</pre></blockquote>

	At the end of &sect;20.5.2.1 [tuples.cnstr], add the following:
<blockquote><pre><span class="ins">template &lt;class... Types&gt;
  tuple(Types...) -&gt; tuple&lt;VTypes...&gt;;</span></pre>
<blockquote><span class="ins"><em>Remarks: </em>The <tt>VTypes...</tt> are determined
	as follows: Let <em>U<sub>i</sub></em> be <tt>decay_t&lt;<em>T<sub>i</sub></em>&gt;</tt> for
	each <em>T<sub>i</sub></em> in <tt>Types</tt>.
	Then each <em>V<sub>i</sub></em> in <tt>VTypes</tt> is <tt>X&amp;</tt> if <em>U<sub>i</sub></em> equals <tt>reference_wrapper&lt;X&gt;</tt>,
	otherwise <em>V<sub>i</sub></em> is <em>U<sub>i</sub></em>.</span></blockquote></blockquote>

In addition, change the start of &sect;20.5.2.4 [tuple.creation as follows:
<blockquote>In the function descriptions that follow, let <em>i</em> be in the
	range of <tt>[0, sizeof...(TTypes))</tt> in order and let <em>T<sub>i</sub></em>
	be the <em>i<sup>th</sup></em> type in a template parameter pack named
	<tt>TTypes</tt>; let <em>j</em> be in the range <tt>[0, sizeof...(UTypes))</tt>
	in order and <em>U<sub>j</sub></em> be the <em>j<sup>th</sup></em> type in a 
	template parameter pack named <tt>UTypes</tt>, where indexing is zero-based.<p/>
	
	
<pre>template &lt;class... Types&gt;
  constexpr <span class="del">tuple&lt;<em>VTypes...</em>&gt;</span><span class="ins">decltype(tuple(declval&lt;Types&amp;&amp;&gt;()...))</span> make_tuple(Types&amp;&amp;... t);</pre><p/>
<blockquote><span class="del">Let <em>U<sub>i</sub></em> be <tt>decay_t&lt;<em>T<sub>i</sub></em>&gt;</tt> for
	each <em>T<sub>i</sub></em> in <tt>Types</tt>.
	Then each <em>V<sub>i</sub></em> in <tt>VTypes</tt> is <tt>X&amp;</tt> if <em>U<sub>i</sub></em> equals <tt>reference_wrapper&lt;X&gt;</tt>,
	otherwise <em>V<sub>i</sub></em> is <em>U<sub>i</sub></em>.</span><p/>
	<em>Returns: </em><tt>tuple<span class="del">&lt;VTypes...&gt;</span>(std::forward&lt;Types&gt;(t)...)</tt>.</blockquote></blockquote></blockquote>
<h3>&sect;20.6 [optional]</h3>
<tt>optional</tt> exhibits the universal reference interaction described in P0091R3. 
Although the constructor
	<tt>optional&lt;T&gt;::optional(T&amp;&amp;&gt;)</tt> &ldquo;expects&rdquo; an rvalue,
	the corresponding implicit deduction guide takes a universal reference. As pointed
	out in the paper, without an explicit deduction guide, there would be an
	ambiguity among the implicit deduction guides for <tt>optional</tt>, preventing it
	from benefiting from template argument deduction for constructors. We follow the
	suggestion in the paper to resolve this by adding the following explicit deduction
	guide at the end of the class definition for <tt>optional</tt> in &sect;20.6.3
	[optional.object].
<blockquote><pre>  T *val; <span class="comment">// exposition only</span>
};
<span class="ins">
template&lt;class T&gt; optional(T&amp;&amp; t) -&gt; optional&lt;remove_reference_t&lt;T&gt;&gt;;</span></pre></blockquote>

<h3>&sect;20.7 [variant]</h3>
No changes required in this subclause. Note that we do not expect <tt>variant</tt>s to leverage
template type deduction for constructors (outside of copy and move constructors) because
their <em>raison d'etre</em> is their ability to hold types beyond those they were
initialized with.
<h3>&sect;20.8 [any]</h3>
    No changes are required in &sect;20.8
    as it defines no class templates.
<h3>&sect;20.9 [template.bitset]</h3>
No changes required in this subclause. It would be tempting to have <tt>bitset("01101"s)</tt>
deduce <tt>bitset&lt;5&gt;</tt>. However, we feel this is best left for a future proposal, likely
after a clearer consensus around compile-time strings has been achieved.
<h3>&sect;20.10 [memory]</h3>
No changes required in this subclause. Note that 
<code>allocator a = allocator&lt;int&gt;();</code> correctly deduces that
<tt>a</tt> has type <tt>allocator&lt;int&gt;</tt> as the constructor
<code>template&lt;class T&gt; template&lt;class U&gt; allocator&lt;T&gt;::allocator&lt;T&gt;(const allocator&lt;U&gt; &amp;)</code>
is not deducible.
<h3>&sect;20.11 [smartptr]</h3>
We add a deduction guide to enable code such as
<code>int *ip = new int();
unique_ptr uip{ip};  <scan class="comment">// Deduce unique_ptr&lt;int&gt;</scan></code>
Note that the template parameter still needs to be given explicitly for arrays.
<code>int *ip = new int[5];
unique_ptr uip{ip};  <span class="comment">// Error. Deduces unique_ptr&lt;int&gt;</span>
unique_ptr aip&lt;int[]&gt;{ip};  <span class="comment">// Ok</span></code>
At the end of the <tt>unique_ptr</tt> class definition in &sect;20.11.1.2 [unique.ptr.single],
add the following:
<blockquote><pre>    <span class="comment">// disable copy from lvalue</span>
    unique_ptr(const unique_ptr&amp;) = delete;
	unique_ptr&amp; operator=(const unique_ptr&amp;) = delete;
  };
  
<span class="ins">  template&lt;class T&gt; unique_ptr(T*) -&gt; unique_ptr&lt;T, default_delete&lt;T&gt;;
  template&lt;class T, class V&gt; unique_ptr(T*, V) -&gt; unique_ptr&lt;T, default_delete&lt;T, V&gt;;  <span class="comment"> // If V::pointer is not valid</em></span>
  template&lt;class U, class V&gt; unique_ptr(U, V) -&gt; unique_ptr&lt;pointer_traits&lt;V::pointer&gt;element_type, V&gt;;  <span class="comment">// If V::pointer is valid</span>
}</pre></blockquote>
Note that analogous changes are necessary for <tt>shared_ptr</tt>, etc. as they do not include the
deleter type as a template parameter.
<h3>&sect;20.12 [memory.resource]</h3>
No changes are required in this subclause as the <tt>polymorphic_allocator&lt;Tp&gt;</tt> constructors do not contain any information about <tt>Tp</tt> (except when constructed
from other <tt>polymorphic_allocator</tt> objects, in which case deduction is properly
done without any changes required)
<h3>&sect;20.13 [allocator.adaptor]</h3>
We supply an explicit deduction guide so that <tt>scoped_allocator_adaptor</tt> can
deduce its outer allocator. At the end of the definition of class <tt>scoped_allocator_adaptor</tt>
in &sect;20.13.1 [allocator.adaptor.syn], add
<blockquote><pre>    scoped_allocator_adaptor select_on_container_copy_construction() const;
  };
 
 <span class="ins">template&lt;class OuterAlloc, class... InnerAllocs&gt; scoped_allocator_adaptor(OuterAlloc&amp;&amp;, const InnerAllocs&amp;&amp; -&gt; scoped_allocator_adaptor&lt;remove_reference_t&lt;OuterAlloc&gt;, remove_reference_t&lt;InnerAllocs&gt;...&gt;;</span></pre></blockquote>If a different outer allocator is desired, then
it can still be specified explicitly. 
<h3>&sect;20.14 [function.objects]</h3>
<tt>reference_wrapper</tt> benefits from template deduction for 
constructors with no wording changes. 
We suggest allowing <tt>function</tt> to deduce its template argument when initialized
by a function or member pointer. Add the following deduction guides at the end of the
class definition for <tt>function</tt> in &sect;20.14.12.2 [func.wrap.func]
<blockquote><pre>    template&lt;class T&gt; const T* target() const noexcept;

  };
  
<span class="ins">  template&lt;class R, class... ArgTypes&gt; 
    function(R(*)(ArgTypes...)) -&gt; function&lt;R(ArgTypes...)&gt;;
  template&lt;class R, class C, class... ArgTypes&gt;
    function(R(C::*)(ArgTypes...)) -&gt; function&lt;R(C &amp;, ArgTypes...)&gt;;
  template&lt;class R, class C, class... ArgTypes&gt; 
    function(R(C::*)(ArgTypes...) const) -&gt; function&lt;R(C const &amp;, ArgTypes...)&gt;;
  template&lt;class R, class C, class... ArgTypes&gt;
    function(R(C::*)(ArgTypes...) volatile) -&gt; function&lt;R(C volatile &amp;, ArgTypes...)&gt;;
  template&lt;class R, class C, class... ArgTypes&gt;
    function(R(C::*)(ArgTypes...) const volatile) -&gt; function&lt;R(C const volatile &amp;, ArgTypes...)&gt;
  template&lt;class R, class C&gt; function(R C::*)) -&gt;
    function&lt;R&amp;(C &amp;)&gt;
  template&lt;class R, class C&gt;
    function(const R C::*)) -&gt; function&lt;const R&amp;(C const &amp;)&gt;
  template&lt;class R, class C&gt;
    function(volatile R C::*)) -&gt; function&lt;volatile R&amp;(volatile C &amp;)&gt;
  template&lt;class R, class C&gt;
    function(const volatile R C::*)) -&gt; function&lt;const volatile R&amp;(const volatile C &amp;)&gt;
</span></pre></blockquote>
<b>Note:</b> There are some arbitrary choices in the deductions for member pointers. We
would be interested to see if the comittee agrees with having deduction guides for member
pointers in addition to function pointers, and if so, whether these are the right choices.<p/>
Since template constructor deduction can be used to construct objects of type <tt>default_searcher</tt>, <tt>boyer_moore_searcher</tt>,
and <tt>boyer_moore_horspool_searcher</tt>, we propose getting rid of the searcher creation functions by
modifying &sect;20.14p2 as follows:
<blockquote><pre>  <span class="comment">// 20.14.13 searchers:</span>
  template&lt;class ForwardIterator, class BinaryPredicate = equal_to&lt;&gt;&gt;
    class default_searcher;
  template&lt;class RandomAccessIterator,
              class Hash = hash&lt;typename iterator_traits&lt;RandomAccessIterator&gt;::value_type&gt;,
			  class BinaryPredicate = equal_to&lt;&gt;&gt;
    class boyer_moore_searcher;
  template&lt;class RandomAccessIterator,
              class Hash = hash&lt;typename iterator_traits&lt;RandomAccessIterator&gt;::value_type&gt;,
			  class BinaryPredicate = equal_to&lt;&gt;&gt;
    class boyer_moore_horspool_searcher;
	
<span class="del">  template&lt;class ForwardIterator, class BinaryPredicate = equal_to&lt;&gt;&gt;
  default_searcher&lt;ForwardIterator, BinaryPredicate&gt;
  make_default_searcher(ForwardIterator pat_first, ForwardIterator pat_last,
	                      BinaryPredicate pred = BinaryPredicate());
  template&lt;class RandomAccessIterator,
              class Hash = hash&lt;typename iterator_traits&lt;RandomAccessIterator&gt;::value_type&gt;,
	          class BinaryPredicate = equal_to&lt;&gt;&gt;
  boyer_moore_searcher&lt;RandomAccessIterator, Hash, BinaryPredicate&gt;
  make_boyer_moore_searcher(
    RandomAccessIterator pat_first, RandomAccessIterator pat_last,
	  Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate());
  template&lt;class RandomAccessIterator,
              class Hash = hash&lt;typename iterator_traits&lt;RandomAccessIterator&gt;::value_type&gt;,
	          class BinaryPredicate = equal_to&lt;&gt;&gt;
  boyer_moore_searcher&lt;RandomAccessIterator, Hash, BinaryPredicate&gt;
  make_boyer_moore_horspool_searcher(
      RandomAccessIterator pat_first, RandomAccessIterator pat_last,
	  Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate());</span>
    
  <span class="comment">// 20.14.14, hash function primary template:</span>
	</pre></blockquote>
Delete &sect;20.14.13.1.1 [func.searchers.default.creation]
<blockquote><span class="del"><b>2014.13.2.1  <tt>boyer_moore_searcher</tt> creation functions [func.searcher.boyer_moore.creation]</b></span>
	<pre><span class="del">  template&lt;class ForwardIterator, class BinaryPredicate = equal_to&lt;&gt;&gt;
  default_searcher&lt;ForwardIterator, BinaryPredicate&gt;
  make_default_searcher(ForwardIterator pat_first, RandomAccessIterator pat_last,
	                    BinaryPredicate pred = BinaryPredicate());</span></pre>
<blockquote><span class="del"><em>Effects:</em> Equivalent to:</span><pre><span class="del">
  return default_searcher&lt;ForwardIterator, BinaryPredicate&gt;(pat_first, pat_last, pred);</span></pre></blockquote></blockquote>
Delete &sect;20.14.13.2.1 [func.searchers.boyer_moore.creation]
<blockquote><span class="del"><b>2014.13.2.1  <tt>boyer_moore_searcher</tt> creation functions [func.searcher.boyer_moore.creation]</b></span>
	<pre><span class="del">  template&lt;class RandomAccessIterator,
           class Hash = hash&lt;typename iterator_traits&lt;RandomAccessIterator&gt;::value_type&gt;,
           class BinaryPredicate = equal_to&lt;&gt;&gt;
  boyer_moore_searcher&lt;RandomAccessIterator, Hash, BinaryPredicate&gt;
  make_boyer_moore_searcher(
    RandomAccessIterator pat_first, RandomAccessIterator pat_last,
	  Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate());</span></pre>
<blockquote><span class="del"><em>Effects:</em> Equivalent to:</span><pre><span class="del">
  return boyer_moore_searcher&lt;RandomAccessIterator, Hash, BinaryPredicate&gt;(
           pat_first, pat_last, hf, pred);</span></pre></blockquote></blockquote>
Delete &sect;20.14.13.3.1 [func.searchers.boyer_moore_horspool.creation]
<blockquote><span class="del"><b>2014.13.2.1  <tt>boyer_moore_searcher</tt> creation functions [func.searcher.boyer_moore.creation]</b></span>
	<pre><span class="del">  template&lt;class RandomAccessIterator,
           class Hash = hash&lt;typename iterator_traits&lt;RandomAccessIterator&gt;::value_type&gt;,
           class BinaryPredicate = equal_to&lt;&gt;&gt;
  boyer_moore_horspool_searcher&lt;RandomAccessIterator, Hash, BinaryPredicate&gt;
  make_boyer_moore_horspool_searcher(
    RandomAccessIterator pat_first, RandomAccessIterator pat_last,
	  Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate());</span></pre>
<blockquote><span class="del"><em>Effects:</em> Equivalent to:</span><pre><span class="del">
  return boyer_moore_searcher&lt;RandomAccessIterator, Hash, BinaryPredicate&gt;(
           pat_first, pat_last, hf, pred);</span></pre></blockquote></blockquote><p/>
<h3>&sect;20.15 [meta]</h3>
Since the classes in this subclause are designed primarily for compile-time metaprogramming, they do not have
constructors that require special treatment as a result of template deduction for constructors.

<h3>&sect;20.16 [ratio]</h3>
Since the classes in this subclause are designed primarily for compile-time metaprogramming, they do not have
constructors that require special treatment as a result of template deduction for constructors.

<h3>&sect;20.17 [time]</h3>
No wording changes necessary for &sect;20.17 to leverage template 
deduction for constructors. Constructs like <tt>duration(5L)</tt> behave as expected
from the compiler-generated implicit deduction guides.</tt>.
<h3>&sect;20.18 [type.index]</h3>
There are no class templates defined in this subclause, so nothing to do.

<h3>&sect;20.19 [execpol]</h3>
The only class template in this subclause is the type trait <tt>is_execution_policy</tt>, so no changes are required as 
described in &sect;20.15 above.
<h2>&sect;21 [strings]</h2>
The string library can take advantage of template argument deduction for constructors with no wording
changes. For example, <tt>basic_string_view("foo")</tt> correctly deduces that <tt>charT</tt> is <tt>char</tt>.
<p/>It is worth noting that, while no wording changes are required, a library vendor may 
choose to make code changes in accordance with the &ldquo;as-if&rdquo;
rule (&sect;1.9 footnote 5) as illustrated by the following example. Suppose
a vendor has previously leveraged the
&ldquo;as-if&rdquo; rule to implement the constructor
<code>basic_string&lt;charT, traits, Allocator&gt;::basic_string(const charT* str, const Allocator&amp; a = Allocator());</code> using the equivalent but non-deducible type <tt>value_type</tt> in place of <tt>charT</tt>
as follows:
<code>basic_string&lt;charT, traits, Allocator&gt;::basic_string(const value_type* str, const Allocator&amp; a = Allocator());</code>
The vendor could maintain this convention while continuing to satisfy the &ldquo;as-if&rdquo; rule in C++17
by adding the following <em>deduction-guide</em>
<code>template&lt;class charT, class traits = char_traits&lt;charT&gt;, class Allocator = allocator&lt;charT&gt;&gt;
  basic_string(const charT*, const Allocator& = Allocator()) -&gt; basic_string&lt;charT, Allocator&gt;;</code>
Similar considerations apply to <tt>basic_string_view</tt>.
<h2>&sect;22 [localization]</h2>
Add the following to the end of the definition of class <tt>wstring_convert</tt> in &sect;22.3.3.2.2
[conversions.string] 
<blockquote><pre>    size_t cvtcount;      <span class="comment">// exposition only</span>
  };
  
<span class="ins">  template&lt;class Codecvt,&gt;
    wstring_convert(Codecvt *, typename Codecvt::state_type) 
      -&gt; wstring_convert&lt;Codecvt, std::allocator&lt;wchar_t&gt;, std::allocator&lt;char&gt;&gt;;
</span></pre></blockquote>
In addition to the above explicit deduction guide, <tt>wstring_convert</tt>
and <tt>wbuffer_convert</tt> (&sect;22.3.3.2.3) benefit from additional implicit deduction guides.

<h2>&sect;23 [containers]</h2>
All of the headers in &sect;23 are listed in
    &ldquo;Table 102 &mdash; Containers library summary&rdquo; in &sect;23.1:
    </p><table border="1"><tbody><tr><th></th><th>Subclause</th><th>Header(s)</th></tr>
    <tr><td>23.2</td><td>Requirements</td><td></td></tr>
    <tr><td>23.3</td><td>Sequence containers</td><td><tt>&lt;array&gt;<br/>&lt;deque&gt;<br/>&lt;forward_list&gt;<br/>&lt;list&gt;<br/>&lt;vector&gt;</tt></td></tr>
    <tr><td>23.4</td><td>Associative containers</td><td><tt>&lt;map&gt;<br/>&lt;set&gt;</tt></td></tr>
    <tr><td>23.5</td><td>Unordered associative containers</td><td><tt>&lt;unordered_map&gt;<br/>&lt;unordered_set&gt;</tt></td></tr>
    <tr><td>23.6</td><td>Container adaptors</td><td><tt>&lt;queue&gt;<br/>&lt;stack&gt;</tt></td></tr>
    </tbody></table>
The only wording change in &sect;23 is to add deduction guides for constructing
containers from iterators as described in &ldquo;Explicitly specified Deduction Guides&rdquo;
in <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0091r3.html">P0091R3</a>,
but we have to make that change many times as follows:
<h3>&sect;23.2 [container.requirements]</h3>
Modify &sect;23.2.3p14 [sequence.reqmts] as follows:
<blockquote>For every sequence container defined in this clause and in clause 21:
<ul><li>If the constructor<blockquote><pre>template &lt;class InputIterator&gt;
X(InputIterator first, InputInterator last,
  const allocator_type&amp; alloc = allocator_type())</pre></blockquote>
    is called with a type <tt>InputIterator</tt> that does not qualify as an
    input iterator, then the constructor shall not participate in overload resolution.</li>
<li><span class="ins">If the <em>deduction-guide </em><blockquote><pre><span class="ins">template &lt;class InputIterator, class Allocator = allocator&lt;typename InputIterator::value_type&gt;&gt;
X(InputIterator, InputIterator,
  const Allocator&amp; = Allocator())
    -&gt; X&lt;typename InputIterator::value_type, Allocator&gt;;</span></pre></blockquote>
    is called with a type <tt>InputIterator</tt> that does not qualify as an
    input iterator, then the <em>deduction-guide</em> shall not participate in overload resolution.</span></li>
<li>If the member functions of the forms:</li></ul></blockquote>
<h3>&sect;23.3 [sequences]</h3>
At the end of the definition of class <tt>deque</tt> in &sect;23.3.8.1 [deque.overview],
add the following <em>deduction-guide</em>:
<blockquote><pre>    void clear() noexcept;
  };
  
<span class="ins">  template &lt;class InputIterator, class Allocator = allocator&lt;typename InputIterator::value_type&gt;&gt;
  deque(InputIterator, InputIterator,
        const Allocator&amp; = Allocator())
    -&gt; deque&lt;typename InputIterator::value_type, Allocator&gt;;</span></pre></blockquote>

At the end of the definition of class <tt>forward_list</tt> in &sect;23.3.9.1 [forwardlist.overview],
add the following <em>deduction-guide</em>:
<blockquote><pre>    void reverse() noexcept;
  };
  
<span class="ins">  template &lt;class InputIterator, class Allocator = allocator&lt;typename InputIterator::value_type&gt;&gt;
  forward_list(InputIterator, InputIterator,
               const Allocator&amp; = Allocator())
    -&gt; forward_list&lt;typename InputIterator::value_type, Allocator&gt;;</span></pre></blockquote>
At the end of the definition of class <tt>list</tt> in &sect;23.3.10.1 [list.overview],
add the following <em>deduction-guide</em>s:
<blockquote><pre>    void reverse() noexcept;
  };
  
<span class="ins">  template &lt;class InputIterator, class Allocator = allocator&lt;typename InputIterator::value_type&gt;&gt;
  list(InputIterator first, InputIterator last,
       const Allocator&amp; = Allocator())
    -&gt; list&lt;typename InputIterator::value_type, Allocator&gt;;</span></pre></blockquote>
At the end of the definition of class <tt>vector</tt> in &sect;23.3.11.1 [vector.overview],
add the following <em>deduction-guide</em>:
<blockquote><pre>    void clear() noexcept;
  };
  
<span class="ins">  template &lt;class InputIterator, class Allocator = allocator&lt;typename InputIterator::value_type&gt;&gt;
  vector(InputIterator, InputIterator,
         const Allocator&amp; = Allocator())
    -&gt; vector&lt;typename InputIterator::value_type, Allocator&gt;;</span></pre></blockquote>
<h3>&sect;23.4 [associative]</h3>
At the end of the definition of class <tt>map</tt> in &sect;23.4.4.1 [map.overview],
add the following <em>deduction-guide</em>s:
<blockquote><pre>    template &lt;class K&gt;
      pair&lt;const_iterator, const_iterator&gt; equal_range(const K&amp; x) const;
  };
  
<span class="ins">  template &lt;class InputIterator, 
        class Compare = default_order_t&lt;typename InputIterator::value_type::first_type&gt;,
        class Allocator = allocator&lt;pair&lt;typename InputIterator::value_type&gt;&gt;
  map(InputIterator, InputIterator, 
      const Compare&amp; = Compare(), const Allocator&amp; = Allocator())
    -&gt; map&lt;typename InputIterator::value_type::first_type,
           typename InputIterator::value_type::second_type,
           Compare, Allocator&gt;;</span>

<span class="ins">  template &lt;class InputIterator, 
        class Allocator = allocator&lt;pair&lt;typename InputIterator::value_type&gt;&gt;
  map(InputIterator, InputIterator, const Allocator&amp; = Allocator())
    -&gt; map&lt;typename InputIterator::value_type::first_type,
           typename InputIterator::value_type::second_type,
           default_order_t&lt;typename InputIterator::value_type::first_type&gt;, Allocator&gt;;</span></pre>
</blockquote>
Note that this always deduces <tt>const</tt> keys. We would like
feedback from the committee as to whether this is the right choice.<p/>
At the end of the definition of class <tt>multimap</tt> in &sect;23.4.5.1 [multimap.overview],
add the following <em>deduction-guide</em>s:
<blockquote><pre>    template &lt;class K&gt;
      pair&lt;const_iterator, const_iterator&gt; equal_range(const K&amp; x) const;
  };
  
<span class="ins">  template &lt;class InputIterator, 
        class Compare = default_order_t&lt;typename InputIterator::value_type::first_type&gt;,
        class Allocator = allocator&lt;pair&lt;typename InputIterator::value_type&gt;&gt;
  multimap(InputIterator, InputIterator, 
      const Compare&amp; = Compare(), const Allocator&amp; = Allocator())
    -&gt; multimap&lt;typename InputIterator::value_type::first_type,
           typename InputIterator::value_type::second_type,
           Compare, Allocator&gt;;</span>

<span class="ins">  template &lt;class InputIterator, 
        class Allocator = allocator&lt;pair&lt;typename InputIterator::value_type&gt;&gt;
  multimap(InputIterator, InputIterator, const Allocator&amp; = Allocator())
    -&gt; multimap&lt;typename InputIterator::value_type::first_type,
           typename InputIterator::value_type::second_type,
           default_order_t&lt;typename InputIterator::value_type::first_type&gt;, Allocator&gt;;</span></pre></blockquote>

At the end of the definition of class <tt>set</tt> in &sect;23.4.6.1 [set.overview],
add the following <em>deduction-guide</em>:
<blockquote><pre>    template &lt;class K&gt;
      pair&lt;const_iterator, const_iterator&gt; equal_range(const K&amp; x) const;
  };
  
<span class="ins">  template &lt;class InputIterator, 
        class Compare = default_order_t&lt;typename InputIterator::value_type&gt;,
        class Allocator = allocator&lt;pair&lt;typename InputIterator::value_type&gt;&gt;
  set(InputIterator, InputIterator, 
      const Compare&amp; = Compare(), const Allocator&amp; = Allocator())
    -&gt; set&lt;typename InputIterator::value_type, Compare, Allocator&gt;;</span>

<span class="ins">  template &lt;class InputIterator, 
        class Allocator = allocator&lt;pair&lt;typename InputIterator::value_type&gt;&gt;
  set(InputIterator, InputIterator, const Allocator&amp; = Allocator())
    -&gt; set&lt;typename InputIterator::value_type,
           default_order_t&lt;typename InputIterator::value_type&gt;, Allocator&gt;;</span></pre></blockquote>

At the end of the definition of class <tt>multiset</tt> in &sect;23.4.7.1 [multiset.overview],
add the following <em>deduction-guide</em>:
<blockquote><pre>    template &lt;class K&gt;
      pair&lt;const_iterator, const_iterator&gt; equal_range(const K&amp; x) const;
  };
  
<span class="ins">  template &lt;class InputIterator, 
        class Compare = default_order_t&lt;typename InputIterator::value_type&gt;,
        class Allocator = allocator&lt;pair&lt;typename InputIterator::value_type&gt;&gt;
  multiset(InputIterator, InputIterator, 
      const Compare&amp; = Compare(), const Allocator&amp; = Allocator())
    -&gt; multiset&lt;typename InputIterator::value_type, Compare, Allocator&gt;;</span>

<span class="ins">  template &lt;class InputIterator, 
        class Allocator = allocator&lt;pair&lt;typename InputIterator::value_type&gt;&gt;
  multiset(InputIterator, InputIterator, const Allocator&amp; = Allocator())
    -&gt; multiset&lt;typename InputIterator::value_type,
           default_order_t&lt;typename InputIterator::value_type&gt;, Allocator&gt;;</span></pre></blockquote>

<h3>&sect;23.5 [unord]</h3>
At the end of the definition of class <tt>unordered_map</tt> in &sect;23.5.4.1 [unord.map.overview],
add the following <em>deduction-guide</em>s:
<blockquote><pre>    void reserve(size_type n);
  };
  
<span class="ins">  template &lt;class InputIterator, 
        class Hash = hash&lt;typename InputIterator::value_type::first_type&gt;,
        class Pred = std::equal_to&lt;typename InputIterator::value_type::first_type&gt;,
        class Allocator = allocator&lt;pair&lt;typename InputIterator::value_type&gt;&gt;
  unordered_map(InputIterator, InputIterator,
      size_type = <em>see_below</em>,
      const Hash&amp; = Hash(), const Pred&amp; = Pred(), const Allocator&amp; = Allocator())
    -&gt; unordered_map&lt;typename InputIterator::value_type::first_type,
           typename InputIterator::value_type::second_type,
           Hash, Pred, Allocator&gt;;</span>

<span class="ins">  template &lt;class InputIterator, 
        class Allocator = allocator&lt;pair&lt;typename InputIterator::value_type&gt;&gt;
  unordered_map(InputIterator, InputIterator, size_type, const Allocator&amp; = Allocator())
    -&gt; unordered_map&lt;typename InputIterator::value_type::first_type,
           typename InputIterator::value_type::second_type,
           hash&lt;typename InputIterator::value_type::first_type&gt;,
           std::equal_to&lt;typename InputIterator::value_type::first_type&gt;,
           Allocator&gt;;</span>

<span class="ins">  template &lt;class InputIterator, 
        class Hash = hash&lt;typename InputIterator::value_type::first_type&gt;,
        class Allocator = allocator&lt;pair&lt;typename InputIterator::value_type&gt;&gt;
  unordered_map(InputIterator, InputIterator, size_type,
       const Hash&amp; = Hash(), const Allocator&amp; = Allocator())
    -&gt; unordered_map&lt;typename InputIterator::value_type::first_type,
           typename InputIterator::value_type::second_type, Hash,
           std::equal_to&lt;typename InputIterator::value_type::first_type&gt;, Allocator&gt;;</span>
</pre>
</blockquote>
Note that this always deduces <tt>const</tt> keys. We would like
feedback from the committee as to whether this is the right choice.<p/>
At the end of the definition of class <tt>unordered_multimap</tt> in &sect;23.5.5.1 [unord.multimap.overview],
add the following <em>deduction-guide</em>:s
<blockquote><pre>    void reserve(size_type n);
  };
  
<span class="ins">  template &lt;class InputIterator, 
        class Hash = hash&lt;typename InputIterator::value_type::first_type&gt;,
        class Pred = std::equal_to&lt;typename InputIterator::value_type::first_type&gt;,
        class Allocator = allocator&lt;pair&lt;typename InputIterator::value_type&gt;&gt;
  unordered_multimap(InputIterator, InputIterator,
      size_type = <em>see_below</em>,
      const Hash&amp; = Hash(), const Pred&amp; = Pred(), const Allocator&amp; = Allocator())
    -&gt; unordered_multimap&lt;typename InputIterator::value_type::first_type,
           typename InputIterator::value_type::second_type,
           Hash, Pred, Allocator&gt;;</span>

<span class="ins">  template &lt;class InputIterator, 
        class Allocator = allocator&lt;pair&lt;typename InputIterator::value_type&gt;&gt;
  unordered_multimap(InputIterator, InputIterator, size_type,
                     const Allocator&amp; = Allocator())
    -&gt; unordered_multimap&lt;typename InputIterator::value_type::first_type,
           typename InputIterator::value_type::second_type,
           hash&lt;typename InputIterator::value_type::first_type&gt;,
           std::equal_to&lt;typename InputIterator::value_type::first_type&gt;,
           Allocator&gt;;</span>

<span class="ins">  template &lt;class InputIterator, 
        class Hash = hash&lt;typename InputIterator::value_type::first_type&gt;,
        class Allocator = allocator&lt;pair&lt;typename InputIterator::value_type&gt;&gt;
  unordered_multimap(InputIterator, InputIterator, size_type,
       const Hash&amp; = Hash(), const Allocator&amp; = Allocator())
    -&gt; unordered_multimap&lt;typename InputIterator::value_type::first_type,
           typename InputIterator::value_type::second_type, Hash,
           std::equal_to&lt;typename InputIterator::value_type::first_type&gt;, Allocator&gt;;</span>
</pre>
</blockquote>
At the end of the definition of class <tt>unordered_set</tt> in &sect;23.5.6.1 [unord.set.overview],
add the following <em>deduction-guide</em>s:
<blockquote><pre>    void reserve(size_type n);
  };
  
<span class="ins">  template &lt;class InputIterator, 
        class Hash = hash&lt;typename InputIterator::value_type&gt;,
        class Pred = std::equal_to&lt;typename InputIterator::value_type&gt;,
        class Allocator = allocator&lt;pair&lt;typename InputIterator::value_type&gt;&gt;
  unordered_set(InputIterator, InputIterator,
      size_type = <em>see_below</em>,
      const Hash&amp; = Hash(), const Pred&amp; = Pred(), const Allocator&amp; = Allocator())
    -&gt; unordered_set&lt;typename InputIterator::value_type::first_type,
           Hash, Pred, Allocator&gt;;</span>

<span class="ins">  template &lt;class InputIterator, 
        class Allocator = allocator&lt;pair&lt;typename InputIterator::value_type&gt;&gt;
  unordered_set(InputIterator, InputIterator, size_type,
       const Allocator&amp; = Allocator())
    -&gt; unordered_set&lt;typename InputIterator::value_type,
           hash&lt;typename InputIterator::value_type&gt;,
           std::equal_to&lt;typename InputIterator::value_type&gt;,
           Allocator&gt;;</span>

<span class="ins">  template &lt;class InputIterator, 
        class Hash = hash&lt;typename InputIterator::value_type&gt;,
        class Allocator = allocator&lt;pair&lt;typename InputIterator::value_type&gt;&gt;
  unordered_set(InputIterator, InputIterator, size_type,
       const Hash&amp; = Hash(), const Allocator&amp; = Allocator())
    -&gt; unordered_set&lt;typename InputIterator::value_type, Hash,
           std::equal_to&lt;typename InputIterator::value_type&gt;, Allocator&gt;;</span>
</pre></blockquote>

At the end of the definition of class <tt>unordered_multiset</tt> in &sect;23.5.7.1 [unord.multiset.overview],
add the following <em>deduction-guide</em>s:
<blockquote><pre>    void reserve(size_type n);
  };
  
<span class="ins">  template &lt;class InputIterator, 
        class Hash = hash&lt;typename InputIterator::value_type&gt;,
        class Pred = std::equal_to&lt;typename InputIterator::value_type&gt;,
        class Allocator = allocator&lt;pair&lt;typename InputIterator::value_type&gt;&gt;
  unordered_multiset(InputIterator, InputIterator,
      size_type = <em>see_below</em>,
      const Hash&amp; = Hash(), const Pred&amp; = Pred(), const Allocator&amp; = Allocator())
    -&gt; unordered_multiset&lt;typename InputIterator::value_type::first_type,
           Hash, Pred, Allocator&gt;;</span>

<span class="ins">  template &lt;class InputIterator, 
        class Allocator = allocator&lt;pair&lt;typename InputIterator::value_type&gt;&gt;
  unordered_multiset(InputIterator, InputIterator, size_type,
       const Allocator&amp; = Allocator())
    -&gt; unordered_multiset&lt;typename InputIterator::value_type,
           hash&lt;typename InputIterator::value_type&gt;,
           std::equal_to&lt;typename InputIterator::value_type&gt;,
           Allocator&gt;;</span>

<span class="ins">  template &lt;class InputIterator, 
        class Hash = hash&lt;typename InputIterator::value_type&gt;,
        class Allocator = allocator&lt;pair&lt;typename InputIterator::value_type&gt;&gt;
  unordered_multiset(InputIterator, InputIterator, size_type,
       const Hash&amp; = Hash(), const Allocator&amp; = Allocator())
    -&gt; unordered_multiset&lt;typename InputIterator::value_type, Hash,
           std::equal_to&lt;typename InputIterator::value_type&gt;, Allocator&gt;;</span>
</pre></blockquote>

<h3>&sect;23.6 [container.adaptors]</h3>
At the end of the definition of class <tt>priority_queue</tt> in &sect;23.6.5
[priority.queue], add the following <em>deduction-guide</em>s:
<blockquote><pre>
    void swap(priority_queue&amp; q) noexcept(is_nothrow_swappable_v&lt;Container&gt; &amp;&amp;
                                              is_nothrow_swappable_v&lt;Compare&gt;)
      { using std::swap; swap(c, q.c); swap(comp, q.comp); }
  };
  
<span class="ins">  template &lt;class InputIterator, class Container, class Compare&gt;
  priority_queue(InputIterator, InputIterator, const Compare&amp;, const Container&amp;)
    -&gt; priority_queue&lt;typename InputIterator::value_type, Container, Compare&gt;;</span>
  
<span class="ins">  template &lt;class InputIterator,
        class Container = vector&lt;T&gt;,
        class Compare = default_order_t&lt;typename Container::value_type&gt;&gt;
  priority_queue(InputIterator, InputIterator, 
      const Compare&amp; = Compare(), const Container&amp;&amp; = Container())
    -&gt; priority_queue&lt;typename InputIterator::value_type, Container, Compare&gt;;</span>
  
</blockquote>
	<b>Note: </b> If a library implementor uses
<tt>value_type</tt> as a constructor parameter type in place of <tt>T</tt>, they can
support template deduction for class templates &ldquo;as-if&rdquo; they were using
<tt>T</tt> through explicit deduction guides along the lines of the example in &sect;21 above.
</pre>
<!--<h2>TODO:</h2> <ul><li>Is LWG Issue 181 relevant? </li>
<li>Can I use return type deduction for <tt>make_pair</tt> to simplify standard language?</li>
	<li>Should we consider having rvalue references SFINAE to only matching rvalue
	references rather than universal references?</li>
</ul>
-->
</body></html>
