<!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>Some improvements to class template argument deduction integration into the standard library</title>
</head>

<body>
<p>Document number: P0739R0 <br>
Date: 2017-07-13<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>
&nbsp;&nbsp;&nbsp;Stephan T. Lavavej (<a href="mailto:stl@exchange.microsoft.com">stl@exchange.microsoft.com</a>)<br>
Audience: {Library Evolution, Library} Working Group
</p>

<h1>Some improvements to class template argument deduction integration into the standard library</h1>

<h2><tt>scoped_lock</tt> argument order</h2>
As Jonathan Wakely has noted, code like the following does not work:
<code>  mutex m;
  scoped_lock l(m, adopt_lock);
</code>
The point here is that when the compiler attempts to deduce <tt>scoped_lock&lt;m1, adopt_lock&gt;</tt>, there is a
    hard error outside the immediate context as <tt>adopt_lock</tt> is not lockable. Note that the same
    code works fine if <tt>scoped_lock</tt> is replaced by <tt>lock_guard</tt> because <tt>lock_guard</tt>
    does not have a variadic argument. <p>
    We recommend fixing this by moving the <tt>adopt_lock_t</tt> parameter to the front of the parameter list. This
    was not done originally because <tt>scoped_lock</tt> was originally named <tt>lock_guard</tt> and
    had to remain compatible to avoid code breakage, which is no longer a requirement now that <tt>scoped_lock</tt>
    is a different class than <tt>lock_guard</tt>. This is useful to fix because it will encourage
     programmers to migrate to consistent use of <tt>scoped_lock</tt> rather than choosing one or the other
    based on circumstances.
    <h3>Wording</h3>
    In the definition of <tt>class scoped_lock</tt> in &sect;33.4.4.2 [thread.lock.scoped], make the
    following change:
    <blockquote><pre>    explicit scoped_lock(MutexTypes&amp;... m);
    <span class="del">explicit scoped_lock(MutexTypes&amp;... m, adopt_lock_t);</span>
    <span class="ins">explicit scoped_lock(adopt_lock_t, MutexTypes&amp;... m);</span>
    ~scoped_lock();</pre></blockquote>
    Likewise, change &sect;33.4.4.2 [thread.lock.scoped] starting immediately before paragraph 4 as follows:
    <blockquote><pre><span class="del">explicit scoped_lock(MutexTypes&amp;... m, adopt_lock_t);</span>
<span class="ins">explicit scoped_lock(adopt_lock_t, MutexTypes&amp;... m);</span></pre>
    <blockquote><em>Requires:</em> The calling thread owns all the mutexes in <tt>m</tt>.</blockquote></blockquote>
<h2>Enable <tt>variant</tt> support</h2>
The following code fails to compile
<code>variant&lt;int, double&gt; v1(3);
variant v2 = v1;  <span class="comment">// Ill-formed!</span></code>
As this natural code is useful and its failure is confusing, we propose that it be supported.
Indeed, prior to the adoption of p0510r0 banning <tt>variant&lt;&gt;</tt>,
the above code worked as expected since <tt>variant&lt;&gt;</tt> occurs in some deduction
    guides in the overload set. As it is not clear that constructor template argument deduction
    was considered in adopting p0510r0, we would like to consider allowing <tt>variant&lt;&gt;</tt>
    not to produce a hard error in such cases.
<h3>Wording</h3>
    Change &sect;23.7.3.1p16 [variant.ctor] as follows
    <blockquote><em>Remarks: </em> This function shall not participate in overload resolution unless <span class="ins"><tt>sizeof...(Types)</tt> is nonzero, unless</span> <tt>is_same_v&lt;decay_t&lt;T&gt;, variant&gt;</tt> is <tt>false</tt>,
        unless <tt>decay_t&lt;T&gt;</tt> is neither a specialization of <tt>in_place_type_t</tt> nor a specialization
        of <tt>in_place_index_t</tt>, unless <tt>is_constructible_v&lt;T<sub>j</sub>, T&gt;</tt> is <tt>true</tt>, and unless the expression
<tt><em>FUN</em>(std::forward&lt;T&gt;(t))</tt> (with <tt><em>FUN</em></tt> being the above-mentioned set of imaginary functions) is well
formed.
</blockquote>
</body></html>
