<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 3149: DefaultConstructible should require default initialization</title>
<meta property="og:title" content="Issue 3149: DefaultConstructible should require default initialization">
<meta property="og:description" content="C++ library issue. Status: C++20">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue3149.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#C++20">C++20</a> status.</em></p>
<h3 id="3149"><a href="lwg-defects.html#3149">3149</a>. <code>DefaultConstructible</code> should require default initialization</h3>
<p><b>Section:</b> 18.4.12 <a href="https://wg21.link/concept.default.init">[concept.default.init]</a> <b>Status:</b> <a href="lwg-active.html#C++20">C++20</a>
 <b>Submitter:</b> Casey Carter <b>Opened:</b> 2018-08-09 <b>Last modified:</b> 2021-06-06</p>
<p><b>Priority: </b>2
</p>
<p><b>View all other</b> <a href="lwg-index.html#concept.default.init">issues</a> in [concept.default.init].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#C++20">C++20</a> status.</p>
<p><b>Discussion:</b></p>
<p>
<code>DefaultConstructible&lt;T&gt;</code> is equivalent to
<code>Constructible&lt;T&gt;</code> (18.4.11 <a href="https://wg21.link/concept.constructible">[concept.constructible]</a>), which
is equivalent to <code>is_constructible_v&lt;T&gt;</code>
(21.3.6.4 <a href="https://wg21.link/meta.unary.prop">[meta.unary.prop]</a>). Per 21.3.6.4 <a href="https://wg21.link/meta.unary.prop">[meta.unary.prop]</a>
<a href="https://wg21.link/meta.unary.prop#8">paragraph 8</a>:
<blockquote>
<p>The predicate condition for a template specialization
<code>is_­constructible&lt;T, Args...&gt;</code> shall be satisfied if and only if
the following variable definition would be well-formed for some invented
variable <code>t</code>:</p>
<blockquote>
<pre>
T t(declval&lt;Args&gt;()...);
</pre>
</blockquote>
</blockquote>
<code>DefaultConstructible&lt;T&gt;</code> requires that objects of type <code>T</code>
can be
<a href="https://wg21.link/dcl.init#8"><i>value-initialized</i></a>,
rather than
<a href="https://wg21.link/dcl.init#7"><i>default-initialized</i></a>
as intended.
</p>
<p>
The library needs a constraint that requires object types to be
default-initializable: the "rangified" versions of the algorithms in
26.11.3 <a href="https://wg21.link/uninitialized.construct.default">[uninitialized.construct.default]</a> proposed in
<a href="https://wg21.link/p0896">P0896 "The One Ranges Proposal"</a>, for
example. Users will also want a mechanism to provide such a constraint, and
they're likely to choose <code>DefaultConstructible</code> despite its subtle
unsuitability.
</p>
<p>
There are two alternative solutions: (1) change <code>DefaultConstructible</code>
to require <i>default-initialization</i>, (2) change
<code>is_default_constructible_v</code> to require default-initializaton and specify
the concept in terms of the trait. (2) is probably too breaking a change to be
feasible.
</p>

<p><i>[2018-08-20 Priority set to 2 after reflector discussion]</i></p>


<p><strong>Previous resolution [SUPERSEDED]:</strong></p>
<blockquote class="note">
<ol>
<li><p>Modify  [concept.defaultconstructible] as follows:</p>

<blockquote>
<pre>
template&lt;class T&gt;
  concept DefaultConstructible = Constructible&lt;T&gt; <ins>&amp;&amp; see below</ins>;
</pre>
<p>
<ins>-?- Type <code>T</code> models <code>DefaultConstructible</code> only if the variable
definition</ins>
<blockquote>
<pre>
<ins>T t;</ins>
</pre>
</blockquote>
<ins>is well-formed for some invented variable <code>t</code>. Access checking is
performed as if in a context unrelated to <code>T</code>. Only the validity of the
immediate context of the variable initialization is considered.</ins>
</p>
</blockquote>
</li>
</ol>
</blockquote>

<p><i>[2018-08-23 Tim provides updated P/R based on Batavia discussion]</i></p>


<p><i>[2018-10-28 Casey expands the problem statement and the P/R]</i></p>

<p>
During Batavia review of <a href="https://wg21.link/p0896r3">P0896R3</a>, Tim
Song noted that <code>{}</code> is not necessarily a valid initializer for a
<code>DefaultConstructible</code> type. In this sample program
(see <a href="https://godbolt.org/z/I64p_E">Compiler Explorer</a>):
<blockquote>
<pre>
struct S0 { explicit S0() = default; };
struct S1 { S0 x; }; // Note: aggregate
S1 x;   // Ok
S1 y{}; // ill-formed; copy-list-initializes x from {}
</pre>
</blockquote>
<code>S1</code> can be default-initialized, but not list-initialized from an empty
<i>braced-init-list</i>. The consensus among those present was that
<code>DefaultConstructible</code> should prohibit this class of pathological types
by requiring that initialization form to be valid.
</p>

<p><i>[2019 Cologne Wednesday night]</i></p>

<p>Status to Ready</p>

<p><i>[2019-10-07 Casey rebases P/R onto N4830 and incorporates WG21-approved changes from P1754R1]</i></p>

<p><strong>Previous resolution [SUPERSEDED]:</strong></p>
<blockquote class="note">
<p>This wording is relative to <a href="https://wg21.link/n4762">N4762</a>.</p>
<ol>
<li><p>Modify  [concept.defaultconstructible] as follows:</p>

<blockquote>
<pre>
<ins>template&lt;class T&gt;
  inline constexpr bool <i>is-default-initializable</i> = <i>see below</i>; // <i>exposition only</i></ins>

template&lt;class T&gt;
  concept DefaultConstructible = Constructible&lt;T&gt; <ins>&amp;&amp; requires { T{}; } &amp;&amp; <i>is-default-initializable</i>&lt;T&gt;</ins>;
</pre>
<p>
<ins>-?- For a type <code>T</code>, <code><i>is-default-initializable</i>&lt;T&gt;</code> is <code>true</code>
if and only if the variable definition</ins>
<blockquote>
<pre>
<ins>T t;</ins>
</pre>
</blockquote>
<ins>is well-formed for some invented variable <code>t</code>; otherwise it is <code>false</code>. Access checking is
performed as if in a context unrelated to <code>T</code>. Only the validity of the
immediate context of the variable initialization is considered.</ins>
</p>
</blockquote>
</li>
</ol>
</blockquote>
<p>
<a href="https://wg21.link/p1754r1">P1754R1 "Rename concepts to <code>standard_case</code> for
C++20"</a> - as approved by both LEWG and LWG in Cologne - contained instructions to rename the
<code>DefaultConstructible</code> concept to <code>default_initializable</code> "If LWG 3151 is accepted."
<a href="lwg-defects.html#3151" title="ConvertibleTo rejects conversions from array and function types (Status: Resolved)">3151</a><sup><a href="https://cplusplus.github.io/LWG/issue3151" title="Latest snapshot">(i)</a></sup> is the unrelated "<code>ConvertibleTo</code> rejects conversion from array and
function types"; this issue is intended by P1754R1. Since P1754R1 was applied to the working draft
in Cologne, whereas this issue was only made Ready, we should apply the desired renaming to the P/R
of this issue.
</p>

<p><strong>Previous resolution [SUPERSEDED]:</strong></p>
<blockquote class="note">
<p>This wording is relative to <a href="https://wg21.link/n4830">N4830</a>.</p>

<ol>
<li><p>Modify 18.3 <a href="https://wg21.link/concepts.syn">[concepts.syn]</a>, header <code>&lt;concepts&gt;</code> synopsis, as indicated:</p>

<blockquote>
<pre>
[&hellip;]
<i>//  [concept.defaultconstructible], concept default_<del>constructible</del><ins>initializable</ins></i>
template&lt;class T&gt;
concept default_<del>constructible</del><ins>initializable</ins> = <i>see below</i>;
[&hellip;]
</pre>
</blockquote>
</li>

<li><p>Modify  [concept.defaultconstructible] as indicated:</p>

<blockquote>
<p>
<b>18.4.12 Concept <code>default_<del>constructible</del><ins>initializable</ins></code> [concept.default<del>constructible</del><ins>initializable</ins>]</b>
</p>
<pre>
<ins>template&lt;class T&gt;
  inline constexpr bool <i>is-default-initializable</i> = <i>see below</i>; // <i>exposition only</i></ins>

template&lt;class T&gt;
  concept default_<del>constructible</del><ins>initializable</ins> = constructible_from&lt;T&gt; <ins>&amp;&amp; requires { T{}; } &amp;&amp; <i>is-default-initializable</i>&lt;T&gt;</ins>;
</pre>
<p>
<ins>-?- For a type <code>T</code>, <code><i>is-default-initializable</i>&lt;T&gt;</code> is <code>true</code>
if and only if the variable definition</ins>
<blockquote>
<pre>
<ins>T t;</ins>
</pre>
</blockquote>
<ins>is well-formed for some invented variable <code>t</code>; otherwise it is <code>false</code>. Access checking is
performed as if in a context unrelated to <code>T</code>. Only the validity of the
immediate context of the variable initialization is considered.</ins>
</p>
</blockquote>
</li>

<li><p>Modify 18.6 <a href="https://wg21.link/concepts.object">[concepts.object]</a> as indicated:</p>

<blockquote>
<p>
-1- This subclause describes concepts that specify the basis of the value-oriented programming style on which
the library is based.
</p>
<pre>
template&lt;class T&gt;
concept movable = is_object_v&lt;T&gt; &amp;&amp; move_constructible&lt;T&gt; &amp;&amp;
[&hellip;]
template&lt;class T&gt;
concept semiregular = copyable&lt;T&gt; &amp;&amp; default_<del>constructible</del><ins>initializable</ins>&lt;T&gt;;
[&hellip;]
</pre>
</blockquote>
</li>

<li><p>Modify 20.2.2 <a href="https://wg21.link/memory.syn">[memory.syn]</a>, header <code>&lt;memory&gt;</code> synopsis, as indicated:</p>

<blockquote>
<pre>
[&hellip;]
namespace ranges {
  template&lt;<i>no-throw-forward-iterator</i> I, <i>no-throw-sentinel</i>&lt;I&gt; S&gt;
    requires default_<del>constructible</del><ins>initializable</ins>&lt;iter_value_t&lt;I&gt;&gt;
      I uninitialized_default_construct(I first, S last);
  template&lt;<i>no-throw-forward-range</i> R&gt;
    requires default_<del>constructible</del><ins>initializable</ins>&lt;range_value_t&lt;R&gt;&gt;
      safe_iterator_t&lt;R&gt; uninitialized_default_construct(R&amp;&amp; r);

  template&lt;<i>no-throw-forward-iterator</i> I&gt;
    requires default_<del>constructible</del><ins>initializable</ins>&lt;iter_value_t&lt;I&gt;&gt;
      I uninitialized_default_construct_n(I first, iter_difference_t&lt;I&gt; n);
}
[&hellip;]
namespace ranges {
  template&lt;<i>no-throw-forward-iterator</i> I, <i>no-throw-sentinel</i>&lt;I&gt; S&gt;
    requires default_<del>constructible</del><ins>initializable</ins>&lt;iter_value_t&lt;I&gt;&gt;
     I uninitialized_value_construct(I first, S last);
  template&lt;<i>no-throw-forward-range</i> R&gt;
    requires default_<del>constructible</del><ins>initializable</ins>&lt;range_value_t&lt;R&gt;&gt;
      safe_iterator_t&lt;R&gt; uninitialized_value_construct(R&amp;&amp; r);

  template&lt;<i>no-throw-forward-iterator</i> I&gt;
    requires default_<del>constructible</del><ins>initializable</ins>&lt;iter_value_t&lt;I&gt;&gt;
      I uninitialized_value_construct_n(I first, iter_difference_t&lt;I&gt; n);
}
[&hellip;]
</pre>
</blockquote>
</li>

<li><p>Modify 26.11.3 <a href="https://wg21.link/uninitialized.construct.default">[uninitialized.construct.default]</a> as indicated:</p>

<blockquote>
<pre>
namespace ranges {
  template&lt;<i>no-throw-forward-iterator</i> I, <i>no-throw-sentinel</i>&lt;I&gt; S&gt;
    requires default_<del>constructible</del><ins>initializable</ins>&lt;iter_value_t&lt;I&gt;&gt;
      I uninitialized_default_construct(I first, S last);
  template&lt;<i>no-throw-forward-range</i> R&gt;
    requires default_<del>constructible</del><ins>initializable</ins>&lt;range_value_t&lt;R&gt;&gt;
      safe_iterator_t&lt;R&gt; uninitialized_default_construct(Ramp;&amp; r);
}
</pre>
<blockquote>
<p>
-2- <i>Effects:</i> Equivalent to:
<p/>
[&hellip;]
</p>
</blockquote>
<pre>
namespace ranges {
  template&lt;<i>no-throw-forward-iterator</i> I&gt;
    requires default_<del>constructible</del><ins>initializable</ins>&lt;iter_value_t&lt;I&gt;&gt;
      I uninitialized_default_construct_n(I first, iter_difference_t&lt;I&gt; n);
}
</pre>
<blockquote>
<p>
-4- <i>Effects:</i> Equivalent to:
<p/>
[&hellip;]
</p>
</blockquote>
</blockquote>
</li>


<li><p>Modify 26.11.4 <a href="https://wg21.link/uninitialized.construct.value">[uninitialized.construct.value]</a> as indicated:</p>

<blockquote>
<pre>
namespace ranges {
  template&lt;<i>no-throw-forward-iterator</i> I, <i>no-throw-sentinel</i>&lt;I&gt; S&gt;
    requires default_<del>constructible</del><ins>initializable</ins>&lt;iter_value_t&lt;I&gt;&gt;
      I uninitialized_value_construct(I first, S last);
  template&lt;<i>no-throw-forward-range</i> R&gt;
    requires default_<del>constructible</del><ins>initializable</ins>&lt;range_value_t&lt;R&gt;&gt;
      safe_iterator_t&lt;R&gt; uninitialized_value_construct(R&amp;&amp; r);
}
</pre>
<blockquote>
<p>
-2- <i>Effects:</i> Equivalent to:
<p/>
[&hellip;]
</p>
</blockquote>
<pre>
namespace ranges {
  template&lt;<i>no-throw-forward-iterator</i> I&gt;
    requires default_<del>constructible</del><ins>initializable</ins>&lt;iter_value_t&lt;I&gt;&gt;
      I uninitialized_value_construct_n(I first, iter_difference_t&lt;I&gt; n);
}
</pre>
<blockquote>
<p>
-4- <i>Effects:</i> Equivalent to:
<p/>
[&hellip;]
</p>
</blockquote>
</blockquote>
</li>

<li><p>Modify  [range.semi.wrap] as indicated:</p>

<blockquote>
<p>
-1- Many types in this subclause are specified in terms of an exposition-only class template <code><i>semiregular-box</i></code>.
<code><i>semiregular-box</i>&lt;T&gt;</code> behaves exactly like <code>optional&lt;T&gt;</code> with the following differences:
</p>
<ol style="list-style-type: none">
<li><p>(1.1) &mdash; [&hellip;]</p></li>
<li><p>(1.2) &mdash; If <code>T</code> models <code>default_<del>constructible</del><ins>initializable</ins></code>, the default constructor of
<code><i>semiregular-box</i>&lt;T&gt;</code> is equivalent to:</p>
<blockquote><pre>
constexpr <i>semiregular-box</i>() noexcept(is_nothrow_default_constructible_v&lt;T&gt;)
  : <i>semiregular-box</i>{in_place}
{ }
</pre></blockquote>
</li>
<li><p>(1.3) &mdash; [&hellip;]</p></li>
</ol>
</blockquote>
</li>

<li><p>Modify 25.6.6.2 <a href="https://wg21.link/range.istream.view">[range.istream.view]</a>, Class template <code>basic_istream_view</code> synopsis,
as indicated:</p>

<blockquote>
<pre>
namespace std::ranges {
  [&hellip;]
  template&lt;movable Val, class CharT, class Traits&gt;
    requires default_<del>constructible</del><ins>initializable</ins>&lt;Val&gt; &amp;&amp;
      <i>stream-extractable</i>&lt;Val, CharT, Traits&gt;
  class basic_istream_view : public view_interface&lt;basic_istream_view&lt;Val, CharT, Traits&gt;&gt; {
    [&hellip;]
  }
  [&hellip;]
}
</pre>
</blockquote>
</li>
</ol>
</blockquote>

<p><i>[2019-11-17; Daniel comments and restores wording]</i></p>

<p>
During the Belfast 2019 meeting the concept renaming was not voted in by this issue, but
separately, the accepted wording can be found in <a href="https://wg21.link/p1917r0#3149">P1917R0#3149</a>.
To prevent confusion, the here presented proposed wording has been synchronized with that of the voted in
document.
</p>


<p id="res-3149"><b>Proposed resolution:</b></p>
<p>This wording is relative to <a href="https://wg21.link/n4762">N4762</a>.</p>

<ol>
<li><p>Modify  [concept.defaultconstructible] as follows:</p>

<blockquote>
<pre>
<ins>template&lt;class T&gt;
  inline constexpr bool <i>is-default-initializable</i> = <i>see below</i>; // <i>exposition only</i></ins>

template&lt;class T&gt;
  concept DefaultConstructible = Constructible&lt;T&gt; <ins>&amp;&amp; requires { T{}; } &amp;&amp; <i>is-default-initializable</i>&lt;T&gt;</ins>;
</pre>
<p>
<ins>-?- For a type <code>T</code>, <code><i>is-default-initializable</i>&lt;T&gt;</code> is <code>true</code>
if and only if the variable definition</ins>
<blockquote>
<pre>
<ins>T t;</ins>
</pre>
</blockquote>
<ins>is well-formed for some invented variable <code>t</code>; otherwise it is <code>false</code>. Access checking is
performed as if in a context unrelated to <code>T</code>. Only the validity of the
immediate context of the variable initialization is considered.</ins>
</p>
</blockquote>
</li>
</ol>





</body>
</html>
