<!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;
    text-decoration: underline;
}
.del {
    background-color:#FFA0A0;
    text-decoration:line-through
}    
</style>

<title>Template argument deduction for class templates (Rev. 7)</title>
</head>

<body>
<p>Document number: P0091R4<br>
Revision of <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0091r3.html">P0091R3</a><br>
Date: 2017-02-06<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;Faisal Vali <a href="mailto:faisalv@yahoo.com"> (faisalv@yahoo.com</a>)<br>
&nbsp;&nbsp;&nbsp;Richard Smith (<a href="mailto:richard@metafoo.co.uk">richard@metafoo.co.uk</a>)<br>
Audience: Evolution Working Group
</p>

<h1>Template argument deduction for class templates (Rev. 7)</h1> 
	This paper discusses possible extensions to template argument deduction for class templates
	as described in P0091R3. Please see that paper for background and context.
<h2>Deleted deduction guides</h2>
When C++ automatically generates functions or methods, it generally allows
	the programmer to suppress the generation of the function/method through the use of <tt>= delete;</tt>.
	E.g. <code>struct A {
  A(const A &amp;) = delete;
};

template&lt;typename T&gt;
int f(T t) { return 3; }
template&lt;&gt;
int f&lt;double&gt;(double) = delete;
</code>
It seems very odd that ordinary template functions can be deleted but deduction guides cannot. Indeed, we contend that 
supporting <tt>= delete</tt> for deduction guides not only increases consistency but has worthwhile use cases as well.<p>
Consider the following example from &ldquo;P0433R1: Toward a resolution of US7 and US14: Integrating template
deduction for class templates into the standard library.&rdquo;
	<code>int iarr[] = {1, 2, 3};
int *ip = iarr;
valarray va(ip, 3); <span class="comment">// Deduces valarray&lt;int&gt;</span></code>
The point is that the <tt>valarray&lt;T&gt;::valarray(const T *, size_t)</tt> constructor is a better match
than the <tt>valarray&lt;T&gt;::valarray(const T &amp;, size_t)</tt> constructor, so <tt>valarray&lt;int&gt;</tt> is
preferred over <tt>valarray&lt;int *&gt;</tt>. Given the typical usage of <tt>valarray</tt>, we believe that
this is a reasonable default, and that is what we recommend in P0433R1.<p>
However, suppose we had wanted this deduction to be ambiguous for <tt>valarray</tt> or a similar class. The natural
	way to do this would be to delete the implicit deduction guide that takes a pointer.
<code>template&lt;T&gt; valarray(const T *, size_t) -&gt; valarray&lt;T&gt; = delete;</code>
<h3>Wording</h3>
Modify &sect;8.4.3 [dcl.fct.def.delete] as follows:
<blockquote>A function definition of the form:
	<blockquote><em>attribute-specifier-seq<sub>opt</sub> decl-specifier-seq<sub>opt</sub> declarator virt-specifier-seq<sub>opt</sub></em> <tt>= delete ;</tt></blockquote>
is called a <em>deleted definition</em>. <span class="ins">A <em>deduction-guide</em> (14.9) with a deleted body is also a <em>deleted definition</em></span></blockquote>
Modify &sect;14.9 [temp.deduct.guide] as follows.
	<blockquote><em>deduction-guide:</em><br/>&nbsp;&nbsp;&nbsp;&nbsp;<tt>explicit</tt><sub><em>opt</em></sub> <em>template-name</em> <tt>(</tt> <em>parameter-declaration-clause</em> <tt>) -&gt; </tt> <em> simple-template-id <span class="ins">function-body<sub>opt</sub></span></em> <tt>;</tt>
</blockquote>
Add the following sentence to the end of 14.9p3:
<blockquote>A <em>deduction-guide</em> shall be
declared in the same scope as the corresponding class template.<span class="ins">If the <em>function-body</em> is not <tt>= delete</tt> or <tt>= default</tt>, the program is ill-formed.</span></blockquote>
	
<h2>Copy/move constructor suppression</h2>
Consider the following example from P0433R1. 
<code>optional o(3);  <span class="comment">// Deduces optional&lt;int&gt;</span>
optional o2 = o;  <span class="comment">// Deduces optional&lt;int&gt;</span></code>

 While this seems natural for user code, it is awkward for writers of template libraries
<code>template&lt;typename T&gt; void foo(T t)
{
  optional o = t; <span class="comment">// T=optional&lt;int&gt; => o is optional&lt;int&gt;, which may not be desired in generic code</span>
  optional&lt;T&gt; o2 = t; <span class="comment">// o2 is optional&lt;optional&lt;int&gt;&gt;</span>
}</code>
While library writers can get around this by using explicit arguments as above, we could consider the possible extension
that constructing with a single-element braced initializer would be defined to make the deduction guides implicitly generated
	from the copy and move constructors the least viable overload.
viable constructors.
<code>template&lt;typename T&gt; void foo(T t)
{
  optional o = {t}; <span class="comment">// o is now always optional&lt;T&gt;</span>
}</code>
There are a number of benefits to this approach. It would make it easier for library writers to write generic code without worrying whether
they will invoke a copy constructor. Furthermore, &ldquo;<tt>optional o = {t};</tt>&rdquo; is not a natural
way to invoke a copy constructor anyway. Even better, since template constructor deduction is new, there are no backwards-compatibility
issues to worry about.<p>
The main concern is that this rule does not overlap with natural code for invoking
	a copy constructor. While we believe the <tt>= {t};</tt> approach avoids excessive overlap. If
	direct initialization is needed, code such as<code>optional o{t}; <span class="comment">// Want to leave as copy constructor</span></code> is not appealing as it is commonly used for
	copy construction (also, cf. <a href="http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1467">CWG 1467</a>).
	However, the following syntactically correct but less traditionally natural code can help to avoid the overlap.
<code>optional o({t}); <span class="comment">// Seems OK to prefer optional&lt;T&gt;::optional(T const &amp;) constructor</span></code>
	The other main objection to copy/move constructor suppression is that it is admittedly a hack to get around a 
	problem that could also be avoided by using the C++14 approach of explicitly specifying <tt>optional&lt;T&gt;</tt>.
	Still, worthwhile template programming notations are sometimes considerably more convoluted than this. so we will leave to EWG
	to decide.

</body></html>
