<?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 xml:lang='en' xmlns:svg='http://www.w3.org/2000/svg' xmlns='http://www.w3.org/1999/xhtml'>
<head><meta content='application/xhtml+xml;charset=utf-8' http-equiv='Content-type' /><title>make_array, revision 2</title></head>
<body><!-- maruku -o make_array.html make_array.md --><style type='text/css'>
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>N4065</td></tr>
<tr><th>Date:</th>	<td>2014-06-26</td></tr>
<tr><th>Project:</th>	<td>Programming Language C++, Library 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='make_array_revision_2'>make_array, revision 2</h1>

<h2 id='changes_since_n4031'>Changes since N4031</h2>

<ul>
<li><code>make_array&lt;D&gt;</code> renamed to <code>array_of&lt;D&gt;</code>.</li>

<li>Fixed <em>cv</em>-<code>reference_wrapper&lt;T&gt;</code> detection.</li>
</ul>

<h2 id='changes_since_n3824'>Changes since N3824</h2>

<ul>
<li>Editorial wording updates.</li>

<li>Comments updates.</li>
</ul>

<h2 id='motivation'>Motivation</h2>

<p>We have <code>make_tuple</code>, <code>make_pair</code>, but not <code>make_array</code>, while <code>std::array</code> creation can also benefit from this &#8220;semiofficial&#8221; tuple-like interface to deduce both element type and array bound.</p>

<h2 id='scope'>Scope</h2>

<p><a href='http://cplusplus.github.io/LWG/lwg-closed.html#851'>LWG 851</a> intended to provide a replacement syntax to</p>

<pre><code>array&lt;T, N&gt; a = { E1, E2, ... };</code></pre>

<p>, so the following</p>

<pre><code>auto a = make_array(42u, 3.14);</code></pre>

<p>is well-formed (with additional <code>static_cast</code>s applied inside) because</p>

<pre><code>array&lt;double, 2&gt; = { 42u, 3.14 };</code></pre>

<p>is well-formed.</p>

<p>This paper intends to provide a set of <code>std::array</code> creation interfaces which are comprehensive from both <code>tuple</code>&#8217;s point of view and <code>array</code>&#8217;s point of view, so narrowing is just naturally banned. See more details driven by this direction in <a href='#design_decisions'>Design Decisions</a>.</p>

<h2 id='examples'>Examples</h2>

<pre><code>auto a1 = make_array(2, 3L);        // array&lt;long, 2&gt;
auto ax = make_array(2, 3U);        // error: narrowing

auto a2 = array_of&lt;long&gt;(2, 3U);      // explicit destination type
auto ax = array_of&lt;unsigned&gt;(2, 3U);  // error: narrowing

auto a3 = make_array(&quot;foo&quot;);        // array&lt;char const*, 1&gt;, decayed
auto a4 = to_array(&quot;foo&quot;);          // array&lt;char, 4&gt;</code></pre>

<h2 id='design_decisions'>Design Decisions</h2>

<ul>
<li>
<p>Provide both <code>make_tuple</code>-like, type-deduced interface and raw array style bound-deduced interface.</p>
</li>

<li>
<p>Ban <code>reference_wrapper</code> in the <code>make_tuple</code>-like interface. <code>make_tuple</code> and <code>make_pair</code> have special handling of <code>reference_wrapper</code>, then user might expect that the expression</p>
</li>
</ul>
<div><div><tt>make_array(ref(a), ref(b))</tt></div></div>
<blockquote>
<p>also results in a tuple-like object storing <code>T&amp;</code>. However, <code>std::array</code> does not store &#8220;real&#8221; references, and any attempts to workaround this break the interfaces in different ways. Note that &#8220;doing nothing&#8221; is not an option since, for example, <code>common_type_t&lt;reference_wrapper&lt;int&gt;, reference_wrapper&lt;long&gt;&gt;</code> is <code>long</code>, not reference or <code>reference_wrapper</code>.</p>
</blockquote>

<ul>
<li>A saperated interface to perform constructing from raw array instead of array-to-pointer conversion. <code>make_tuple</code> and <code>make_pair</code> unconditionally decay, but such a behavior, when being applied to <code>make_array</code>,</li>
</ul>
<div><div><tt>make_array("raw array")&nbsp;
// got array&lt;char const&#42;, 1&gt;</tt></div></div>
<blockquote>
<p>is inexplicable. However, to keep the interfaces consistent, I decide to name a new utility differently instead of to ban this conversion.</p>
</blockquote>

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

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

<p>Add to 23.3.1/2 &#91;sequences.general&#93;, <code>&lt;array&gt;</code> synopsis:</p>

<pre><code>namespace std {
  template &lt;class T, size_t N &gt; struct array;</code></pre>

<blockquote>
<p>&#8230;</p>
</blockquote>

<pre><code>  template &lt;class T, size_t N &gt;
    void swap(array&lt;T,N&gt;&amp; x, array&lt;T,N&gt;&amp; y) noexcept(noexcept(x.swap(y)));</code></pre>
<div><ins>
<tt>template &lt;class... Types&gt;</tt><br />
<tt>&nbsp;&nbsp;constexpr <i>see below</i> make_array(Types&amp;&amp;...);</tt><br />
<tt>template &lt;class D, class... Types&gt;</tt><br />
<tt>&nbsp;&nbsp;constexpr <i>see below</i> array_of(Types&amp;&amp;...);</tt><br />
<tt>template &lt;class T, size_t N&gt;</tt><br />
<tt>&nbsp;&nbsp;constexpr <i>see below</i> to_array(T (&amp;a)&#91;N&#93;);</tt><br />
</ins></div>
<blockquote>
<p>&#8230;</p>
</blockquote>

<pre><code>}</code></pre>

<p>New section 23.3.2.9 &#91;array.creation&#93; (between &#91;array.zero&#93; and &#91;array.tuple&#93;, which was 23.3.2.9):</p>

<blockquote>
<h4 id='23329_array_creation_functions_arraycreation'>23.3.2.9 Array creation functions &#91;array.creation&#93;</h4>
</blockquote>

<pre><code>template &lt;class... Types&gt;
  constexpr array&lt;CT, sizeof...(Types)&gt; make_array(Types&amp;&amp;...);</code></pre>

<blockquote>
<p>Let <em>Ui</em> be <code>decay_t&lt;</code><em>Ti</em><code>&gt;</code> for each <em>Ti</em> in <code>Types</code>.</p>
</blockquote>

<blockquote>
<p><em>Remarks:</em> This function shall not participate in overload resolution unless <em>Ui</em> is not <code>reference_wrapper&lt;</code><em>Ti</em><code>&gt;</code> for all <em>i</em>.</p>
</blockquote>

<p><em>[Author&#8217;s note:</em> We allow users to detect and handle this case. <em>&#8211;end note]</em></p>

<blockquote>
<p><em>Returns:</em> <code>array&lt;CT, sizeof...(Types)&gt;{ std::forward&lt;Types&gt;(t))... }</code>, where <code>CT</code> is <code>common_type_t&lt;Types...&gt;</code>.</p>
</blockquote>

<blockquote>
<p><em>[Example:</em></p>
</blockquote>

<pre><code>    int i = 1; int&amp; ri = i;
    make_array(i, ri, 42L)</code></pre>

<blockquote>
<p>creates an <code>array</code> of type</p>
</blockquote>

<pre><code>    array&lt;long, 3&gt;</code></pre>

<blockquote>
<p><em>&#8211;end example]</em></p>
</blockquote>

<pre><code>template &lt;class D, class... Types&gt;
  constexpr array&lt;D, sizeof...(Types)&gt; array_of(Types&amp;&amp;...);</code></pre>

<blockquote>
<p><em>Returns:</em> <code>array&lt;D, sizeof...(Types)&gt;{ std::forward&lt;Types&gt;(t))... }</code>.</p>
</blockquote>

<pre><code>template &lt;class T, size_t N&gt;
  constexpr array&lt;V, N&gt; to_array(T (&amp;a)[N]);</code></pre>

<blockquote>
<p><em>Returns:</em> An <code>array&lt;V, N&gt;</code> such that each element is copy-initialized with the corresponding element of <code>a</code>, where <code>V</code> is <code>remove_cv_t&lt;T&gt;</code>.</p>
</blockquote>

<p><em>[Author&#8217;s note:</em> If <code>std::array</code> is extended to support multidimensional array (<a href='http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3794.html'>N3794</a>), this function might get extended as well, but we don&#8217;t let users to roll their own. On the other hand, if users understand multidimensional <code>std::array</code> as <code>array</code> of <code>array</code>s, it might be more convenient and clear to write</p>

<pre><code>make_array(make_array(1, 2, 3), make_array(4, 5, 6)...)</code></pre>

<p>instead of to adapt a raw array. <em>&#8211;end note]</em></p>

<h2 id='alternative_design'>Alternative Design</h2>

<p>The past two revisions of this paper adds 2 names (<code>make_array</code>, <code>to_array</code>) rather than 3 (with the standalone <code>array_of</code>). If you prefer keeping the number of symbols minimal, or believe that the type&amp;bound-deduced interface and the bound-deduced-only interface should be named the same, <a href='http://students.cs.niu.edu/~z1565938/make_array_r2_void.html'>here</a> is an alternative wording for such a design.</p>

<h2 id='sample_implementation'>Sample Implementation</h2>

<p>A sample implementation is available at <a href='https://gist.github.com/lichray/6034753'>https://gist.github.com/lichray/6034753</a>.</p>

<h2 id='acknowledgments'>Acknowledgments</h2>

<p>Jonathan Wakely, who showed me how <code>index_sequence</code> helps initializing <code>std::array</code> from a raw array.</p>

<p>Daniel Krügler, who explained why an explicit destination type is essential.</p>

<p>Ville Voutilainen and other people who reviewed this paper.</p>

<p>Stephan T. Lavavej, who pointed out the ambiguity issue of the two <code>make_array</code> overloads, and came with with the naming &#8221;<code>*_of</code>&#8221;.</p>
</body></html>
