<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC
    "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN"
    "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:svg="http://www.w3.org/2000/svg" xml:lang="en">
<head><meta http-equiv="Content-type" content="application/xhtml+xml;charset=utf-8" /><title>Deduction guide for</title></head>
<body><!-- maruku -o us148.html us148.md --><style type='text/css'>
pre { margin: 0; }
pre code { display: block; margin-left: 2em; }
div { display: block; margin-left: 2em; }
ins { text-decoration: none; font-weight: bold; background-color: #A0FFA0 }
del { text-decoration: line-through; background-color: #FFA0A0 }
</style><table><tbody>
<tr><th>Doc. no.:</th>	<td>P0511R0</td></tr>
<tr><th>Date:</th>	<td>2016-11-09</td></tr>
<tr><th>Audience:</th>	<td>Library Evolution Working Group</td></tr>
<tr><th>Reply-to:</th>	<td>Zhihao Yuan &lt;zy at miator dot net&gt;</td></tr>
</tbody></table>
<h1 id="deduction_guide_for_">Deduction guide for <code>std::array</code></h1>

<h2 id="abstract">Abstract</h2>

<p>[US 148] suggests to add the following deduction guide to <code>std::array</code></p>

<pre><code>template &lt;class T&gt;
array(T&amp;&amp;...) -&gt; array&lt;common_type_t&lt;T...&gt;, sizeof...(T)&gt;;</code></pre>

<p>, which is similar to <code>make_array</code>‘s behavior as presented in <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2016/n4600.html">N4600</a> Library Fundamentals V2. This paper suggests that rather than deducing to a “common type”, same-decayed type should be required. Meaning,</p>

<pre><code>array{ 1, 2u }</code></pre>

<p>will be banned, and</p>

<pre><code>array{ &quot;literal&quot;, ref_char_ptr }</code></pre>

<p>will be preserved.</p>

<h2 id="discussion">Discussion</h2>

<p>The author of the <code>make_array</code> proposal is aware of several drawbacks with the “common type” behavior and put efforts in the adopted facility to address them. For example, an array of common type can be fragile. The deduced “common type” is often unintended, and a later added element can change the type of the entire array, and this change may not be captured at compile-time. When a user runs into these issues, he/she can switch to <code>make_array&lt;T&gt;</code>, which simply specifies the element type without deduction, but this option is not available to the deduction guide for <code>array</code> since we decided not to deduce a <em>template-id</em>.</p>

<p>The trait <code>common_type_t</code> can also be fragile. A typical example is that, given the deduction guide specified in [US 148] unmodified,</p>

<pre><code>array{ ref(lv_int), ref(lv_int) }</code></pre>

<p>gives <code>array&lt;reference_wrapper&lt;int&gt;&gt;</code> which is not bad, but</p>

<pre><code>array{ ref(lv_int), ref(lv_long) }</code></pre>

<p>will give you an <code>array&lt;long&gt;</code> that is not even mentioning <code>reference_wrapper</code>, and that’s one of the major reasons why <code>make_array</code> banned <code>reference_wrapper</code>. Given the discussion happened in LEWG, we are not sure whether we want to unwrap references with <code>tuple</code> and <code>pair</code>‘s deduction guides and I’m not sure whether I want to do anything special to <code>array</code>’s deduction guide in this area.</p>

<p>The “common type” semantics does not present in other tuple-like types. To rephrase this in an unfortunately academic way, the other two product types, namely <code>tuple</code> and <code>pair</code>, are not trying to promote type arguments to other types with larger ranges and end up with creating types that are no longer product types. A product type such as <code>tuple&lt;X, Y&gt;</code> is called product type because the possible range of values, denoted as <em>|</em><code>tuple&lt;X,Y&gt;</code><em>|</em>, is <em>|</em><code>X</code><em>|×|</em><code>Y</code><em>|</em>, not <em>|</em><code>Wat</code><em>|</em><sup>2</sup>.</p>

<p>Last but not least, it is quite obvious that</p>

<pre><code>vector{ 1, 2.0, 3u }</code></pre>

<p>does not give you a <code>vector&lt;double&gt;</code>, so why expect <code>std::array</code> to do so given exactly the same syntax?</p>

<h2 id="wording">Wording</h2>

<p>This wording is relative to N4606.</p>

<p>Add the following signature to 23.3.7.1 [array.overview]/3:</p>
<div><tt style='white-space: pre'>
    constexpr const T * data() const noexcept;
  };
<ins>
  template&lt;class... T&gt;
    array(T&amp;&amp;...) -> array&lt;<i>see below</i>, sizeof...(T)&gt;;</ins>
}
</tt></div>
<p>Add the following as paragraph 2 to 23.3.7.2 [array.cons]:</p>
<div><tt style='white-space: pre'>
  template&lt;class... T&gt;
    array(T&amp;&amp;...) -> array&lt;<i>D</i>, sizeof...(T)&gt;;
</tt></div>
<blockquote>
<p><em>Remarks:</em> <em><code>D</code></em> is determined as follows: Let <em>U</em><i><sub>i</sub></i> be <code>decay_t&lt;</code><em>T</em><i><sub>i</sub></i><code>&gt;</code> for each <em>T</em><i><sub>i</sub></i> in <code>T</code>. Then <em><code>D</code></em> is <em>U</em><i><sub>0</sub></i> and <code>is_same_v&lt;</code><em><code>D</code></em><code>, </code><em>U</em><i><sub>0</sub></i><code>&gt;</code> is <code>true</code> for all <em>i</em>. If there is no such <em><code>D</code></em>, the program is ill-formed.</p>
</blockquote>

<h2 id="implementation">Implementation</h2>

<p>Tested with gcc-7.0.0: <a href="http://melpon.org/wandbox/permlink/vOFiEZoY467tDjpE">Wandbox</a>.</p>
</body></html>
