<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 851: simplified array construction</title>
<meta property="og:title" content="Issue 851: simplified array construction">
<meta property="og:description" content="C++ library issue. Status: NAD">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue851.html">
<meta property="og:type" content="website">
<meta property="og:image" content="http://cplusplus.github.io/LWG/images/cpp_logo.png">
<meta property="og:image:alt" content="C++ logo">
<style>
  p {text-align:justify}
  li {text-align:justify}
  pre code.backtick::before { content: "`" }
  pre code.backtick::after { content: "`" }
  blockquote.note
  {
    background-color:#E0E0E0;
    padding-left: 15px;
    padding-right: 15px;
    padding-top: 1px;
    padding-bottom: 1px;
  }
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  table.issues-index { border: 1px solid; border-collapse: collapse; }
  table.issues-index th { text-align: center; padding: 4px; border: 1px solid; }
  table.issues-index td { padding: 4px; border: 1px solid; }
  table.issues-index td:nth-child(1) { text-align: right; }
  table.issues-index td:nth-child(2) { text-align: left; }
  table.issues-index td:nth-child(3) { text-align: left; }
  table.issues-index td:nth-child(4) { text-align: left; }
  table.issues-index td:nth-child(5) { text-align: center; }
  table.issues-index td:nth-child(6) { text-align: center; }
  table.issues-index td:nth-child(7) { text-align: left; }
  table.issues-index td:nth-child(5) span.no-pr { color: red; }
  @media (prefers-color-scheme: dark) {
     html {
        color: #ddd;
        background-color: black;
     }
     ins {
        background-color: #225522
     }
     del {
        background-color: #662222
     }
     a {
        color: #6af
     }
     a:visited {
        color: #6af
     }
     blockquote.note
     {
        background-color: rgba(255, 255, 255, .10)
     }
  }
</style>
</head>
<body>
<hr>
<p><em>This page is a snapshot from the LWG issues list, see the <a href="lwg-active.html">Library Active Issues List</a> for more information and the meaning of <a href="lwg-active.html#NAD">NAD</a> status.</em></p>
<h3 id="851"><a href="lwg-closed.html#851">851</a>. simplified array construction</h3>
<p><b>Section:</b> 23.3.3 <a href="https://wg21.link/array">[array]</a> <b>Status:</b> <a href="lwg-active.html#NAD">NAD</a>
 <b>Submitter:</b> Benjamin Kosnik <b>Opened:</b> 2008-06-05 <b>Last modified:</b> 2017-06-06</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View all other</b> <a href="lwg-index.html#array">issues</a> in [array].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#NAD">NAD</a> status.</p>
<p><b>Discussion:</b></p>
<p>
This is an issue that came up on the libstdc++ list, where a
discrepancy between "C" arrays and C++0x's <code>std::array</code> was pointed
out.
</p>

<p>
In "C," this array usage is possible:
</p>

<blockquote><pre>
int ar[] = {1, 4, 6};
</pre></blockquote>

<p>
But for C++, 
</p>

<blockquote><pre>
std::array&lt;int&gt; a = { 1, 4, 6 }; // error
</pre></blockquote>

<p>
Instead, the second parameter of the <code>array</code> template must be
explicit, like so:
</p>

<blockquote><pre>
std::array&lt;int, 3&gt; a = { 1, 4, 6 };
</pre></blockquote>

<p>
Doug Gregor proposes the following solution, that assumes
generalized initializer lists.
</p>

<blockquote><pre>
template&lt;typename T, typename... Args&gt;
inline array&lt;T, sizeof...(Args)&gt; 
make_array(Args&amp;&amp;... args) 
{ return { std::forward&lt;Args&gt;(args)... };  }
</pre></blockquote>

<p>
Then, the way to build an <code>array</code> from a list of unknown size is:
</p>

<blockquote><pre>
auto a = make_array&lt;T&gt;(1, 4, 6);
</pre></blockquote>

<p><i>[
San Francisco:
]</i></p>


<blockquote>
<p>
Benjamin: Move to Ready?
</p>
<p>
Bjarne: I'm not convinced this is useful enough to add, so I'd like us
to have time to reflect on it.
</p>
<p>
Alisdair: the constraints are wrong, they should be
</p>
<blockquote><pre>
template&lt;ValueType T, ValueType... Args&gt;
requires Convertible&lt;Args, T&gt;...
array&lt;T, sizeof...(Args)&gt; make_array(Args&amp;&amp;... args);
</pre></blockquote>
<p>
Alidair: this would be useful if we had a constexpr version.
</p>
<p>
Bjarne: this is probably useful for arrays with a small number of
elements, but it's not clearly useful otherwise.
</p>
<p>
Consensus is to move to Open.
</p>
</blockquote>

<p><i>[
2009-06-07 Daniel adds:
]</i></p>


<blockquote>
<p>
I suggest a fix and a simplification of the current proposal: Recent
prototyping by
Howard showed, that a fix is required because narrowing conversion
9.5.5 <a href="https://wg21.link/dcl.init.list">[dcl.init.list]</a>/6 b.3
would severely limit the possible distribution of argument types, e.g.
the expression
<code>make_array&lt;double&gt;(1, 2.0)</code> is ill-formed, because the narrowing
happens <em>inside</em> the
function body where no constant expressions exist anymore. Furthermore
given e.g.
</p>
<blockquote><pre>
int f();
double g();
</pre></blockquote>
<p>
we probably want to support
</p>
<blockquote><pre>
make_array&lt;double&gt;(f(), g());
</pre></blockquote>

<p>
as well. To make this feasible, the currently suggested expansion
</p>

<blockquote><pre>
{ std::forward&lt;Args&gt;(args)... }
</pre></blockquote>

<p>
needs to be replaced by
</p>

<blockquote><pre>
{ static_cast&lt;T&gt;(std::forward&lt;Args&gt;(args))... }
</pre></blockquote>

<p>
which is safe, because we already ensure convertibility via the
element-wise <code>Convertible&lt;Args, T&gt;</code> requirement. Some other fixes are
necessary: The <code>ValueType</code> requirement for the function <em>parameters</em>
is invalid, because all lvalue arguments will deduce to an lvalue-reference,
thereby no longer satisfying this requirement.
</p>

<p>
The suggested simplification is to provide a default-computed effective
type for the result array based on common_type and decay, in
unconstrained form:
</p>

<blockquote><pre>
template&lt;typename... Args&gt;
array&lt;typename decay&lt;typename common_type&lt;Args...&gt;::type&gt;::type,
sizeof...(Args)&gt;
make_array(Args&amp;&amp;... args);
</pre></blockquote>

<p>
The approach used below is similar to that of <code>make_pair</code> and <code>make_tuple</code>
using a symbol <code>C</code> to represent the decayed common type [Note: Special
handling of <code>reference_wrapper</code> types is intentionally <em>not</em> provided, because
our target has so satisfy <code>ValueType</code>, thus under the revised proposal only
an all-<code>reference_wrapper</code>-arguments would be well-formed and an array of
<code>reference_wrapper</code> will be constructed]. I do currently not suggest to
add new concepts reflecting <code>decay</code> and <code>common_type</code>, but an implementor will
need something like this to succeed. Note that we use a similar fuzziness for
<code>make_pair</code> and <code>make_tuple</code> currently. This fuzziness is not related to
the currently
missing <code>Constructible&lt;Vi, Ti&amp;&amp;&gt;</code> requirement for those functions. The following
proposal fixes that miss for <code>make_array</code>. If the corresponding <code>C</code> type
deduction is
explicitly wanted for standardization, here the implementation
</p>

<blockquote><pre>
auto concept DC&lt;typename... T&gt; {
  typename type = typename decay&lt;typename common_type&lt;T...&gt;::type&gt;::type;
}
</pre></blockquote>

<p>
where <code>C</code> is identical to <code>DC&lt;Args...&gt;::type</code> in the proposed resolution below.
</p>
<p>
I intentionally added no further type relation between type and the concept
template parameters, but instead added this requirement below to make
the specification as transparent as possible. As written this concept is
satisfied, if the corresponding associated type exists.
</p>

<p><b>Suggested Resolution:</b></p>

<ol>
<li>
<p>
Add to the array synopsis in 23.3 <a href="https://wg21.link/sequences">[sequences]</a>:
</p>
<blockquote><pre>
<ins>
template&lt;ReferentType... Args&gt;
requires ValueType&lt;C&gt; &amp;&amp; IdentityOf&lt;Args&gt; &amp;&amp; Constructible&lt;C, Args&amp;&amp;&gt;...
array&lt;C, sizeof...(Args)&gt;
make_array(Args&amp;&amp;... args);
</ins>
</pre></blockquote>
</li>

<li>
<p>
Append after 23.3.3.7 <a href="https://wg21.link/array.tuple">[array.tuple]</a> Tuple interface to class template array
the following new section:
</p>
<blockquote>
<p>
23.4.1.7 Array creation functions [array.creation]
</p>

<pre>
<ins>
template&lt;ReferentType... Args&gt;
requires ValueType&lt;C&gt; &amp;&amp; IdentityOf&lt;Args&gt; &amp;&amp; Constructible&lt;C, Args&amp;&amp;&gt;...
array&lt;C, sizeof...(Args)&gt;
make_array(Args&amp;&amp;... args);</ins>
</pre>

<blockquote>
<p><ins>
Let <code>C</code> be <code>decay&lt;common_type&lt;Args...&gt;::type&gt;::type</code>.
</ins></p>
<p>
<ins><i>Returns:</i> an <code>array&lt;C, sizeof...(Args)&gt;</code> initialized with
<code>{ static_cast&lt;C&gt;(std::forward&lt;Args&gt;(args))... }</code>.
</ins></p>
</blockquote>
</blockquote>

</li>

</ol>

</blockquote>

<p><i>[
2009-07 Frankfurt:
]</i></p>


<blockquote>
<p>
The proposed resolution uses concepts.
</p>
<p>
Daniel to rewrite the proposed resolution.
</p>
<p>
Leave Open.
</p>
</blockquote>

<p><i>[
2009-07-25 Daniel provides rewritten proposed resolution.
]</i></p>


<p><i>[
2009-10 Santa Cruz:
]</i></p>


<blockquote><p>
Argument for NAD future: everything about this could be added on. This
does not require changes to the existing text.
</p></blockquote>

<p><i>[2015-11-29, Alisdair comments]</i></p>

<p>
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4391">N4391</a> was adopted for Fundamentals 2 at the Lenexa meeting.
</p>

<p><i>[2017-02 in Kona, LEWG recommends NAD]</i></p>


<p><i>[2017-06-02 Issues Telecon]</i></p>

<p>It seems as if deduction guides can solve most of the problem. In addition
to that, make_array is available in Library Fundamentals TS v2. If
it's desired to be able to specify the type but not the extent, make_array
can do that, and if make_array isn't acceptable for that, we are talking
about a language extension in deduction guides, which needs a proposal
paper.</p>
<p>Resolve as NAD</p>


<p id="res-851"><b>Proposed resolution:</b></p>

<ol>
<li>
<p>
Add to the array synopsis in 23.3 <a href="https://wg21.link/sequences">[sequences]</a>:
</p>

<blockquote><pre>
<ins>template&lt;class... Args&gt;
  array&lt;<i>CT</i>, sizeof...(Args)&gt;
  make_array(Args&amp;&amp;... args);</ins>
</pre></blockquote>
</li>

<li>
<p>
Append after 23.3.3.7 <a href="https://wg21.link/array.tuple">[array.tuple]</a> "Tuple interface to class template array" the
following new section:
</p>

<blockquote>
<p>
<ins>XX.X.X.X Array creation functions [array.creation]</ins>
</p>

<pre><ins>
template&lt;class... Args&gt;
array&lt;<i>CT</i>, sizeof...(Args)&gt;
make_array(Args&amp;&amp;... args)
</ins></pre>

<blockquote>
<p>
<ins>Let <i>CT</i> be <code>decay&lt;common_type&lt;Args...&gt;::type&gt;::type</code>.</ins>
</p>
<p>
<ins><i>Returns:</i> An <code>array&lt;<i>CT</i>, sizeof...(Args)&gt;</code> initialized with <code>{
static_cast&lt;<i>CT</i>&gt;(std::forward&lt;Args&gt;(args))... }</code>.</ins>
</p>

<p><ins>
[<i>Example:</i>
</ins></p>
<blockquote><pre><ins>
int i = 0; int&amp; ri = i;
make_array(42u, i, 2.78, ri);
</ins></pre></blockquote>
<p><ins>
returns an array of type
</ins></p>
<blockquote><pre><ins>
array&lt;double, 4&gt;
</ins></pre></blockquote>

<p><ins>
&mdash;<i>end example</i>]</ins>
</p>
</blockquote>
</blockquote>
</li>

</ol>








</body>
</html>
