<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang xml:lang>
<head>
  <meta charset="utf-8" />
  <meta name="generator" content="mpark/wg21" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
  <meta name="dcterms.date" content="2023-03-12" />
  <title>Designated-initializers for Base Classes</title>
  <style>
      code{white-space: pre-wrap;}
      span.smallcaps{font-variant: small-caps;}
      span.underline{text-decoration: underline;}
      div.column{display: inline-block; vertical-align: top; width: 50%;}
      div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
      ul.task-list{list-style: none;}
      pre > code.sourceCode { white-space: pre; position: relative; }
      pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
      pre > code.sourceCode > span:empty { height: 1.2em; }
      code.sourceCode > span { color: inherit; text-decoration: inherit; }
      div.sourceCode { margin: 1em 0; }
      pre.sourceCode { margin: 0; }
      @media screen {
      div.sourceCode { overflow: auto; }
      }
      @media print {
      pre > code.sourceCode { white-space: pre-wrap; }
      pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
      }
      pre.numberSource code
        { counter-reset: source-line 0; }
      pre.numberSource code > span
        { position: relative; left: -4em; counter-increment: source-line; }
      pre.numberSource code > span > a:first-child::before
        { content: counter(source-line);
          position: relative; left: -1em; text-align: right; vertical-align: baseline;
          border: none; display: inline-block;
          -webkit-touch-callout: none; -webkit-user-select: none;
          -khtml-user-select: none; -moz-user-select: none;
          -ms-user-select: none; user-select: none;
          padding: 0 4px; width: 4em;
          color: #aaaaaa;
        }
      pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa;  padding-left: 4px; }
      div.sourceCode
        {  background-color: #f6f8fa; }
      @media screen {
      pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
      }
      code span. { } /* Normal */
      code span.al { color: #ff0000; } /* Alert */
      code span.an { } /* Annotation */
      code span.at { } /* Attribute */
      code span.bn { color: #9f6807; } /* BaseN */
      code span.bu { color: #9f6807; } /* BuiltIn */
      code span.cf { color: #00607c; } /* ControlFlow */
      code span.ch { color: #9f6807; } /* Char */
      code span.cn { } /* Constant */
      code span.co { color: #008000; font-style: italic; } /* Comment */
      code span.cv { color: #008000; font-style: italic; } /* CommentVar */
      code span.do { color: #008000; } /* Documentation */
      code span.dt { color: #00607c; } /* DataType */
      code span.dv { color: #9f6807; } /* DecVal */
      code span.er { color: #ff0000; font-weight: bold; } /* Error */
      code span.ex { } /* Extension */
      code span.fl { color: #9f6807; } /* Float */
      code span.fu { } /* Function */
      code span.im { } /* Import */
      code span.in { color: #008000; } /* Information */
      code span.kw { color: #00607c; } /* Keyword */
      code span.op { color: #af1915; } /* Operator */
      code span.ot { } /* Other */
      code span.pp { color: #6f4e37; } /* Preprocessor */
      code span.re { } /* RegionMarker */
      code span.sc { color: #9f6807; } /* SpecialChar */
      code span.ss { color: #9f6807; } /* SpecialString */
      code span.st { color: #9f6807; } /* String */
      code span.va { } /* Variable */
      code span.vs { color: #9f6807; } /* VerbatimString */
      code span.wa { color: #008000; font-weight: bold; } /* Warning */
      code.diff {color: #898887}
      code.diff span.va {color: #006e28}
      code.diff span.st {color: #bf0303}
  </style>
  <style type="text/css">
body {
margin: 5em;
font-family: serif;

hyphens: auto;
line-height: 1.35;
}
div.wrapper {
max-width: 60em;
margin: auto;
}
ul {
list-style-type: none;
padding-left: 2em;
margin-top: -0.2em;
margin-bottom: -0.2em;
}
a {
text-decoration: none;
color: #4183C4;
}
a.hidden_link {
text-decoration: none;
color: inherit;
}
li {
margin-top: 0.6em;
margin-bottom: 0.6em;
}
h1, h2, h3, h4 {
position: relative;
line-height: 1;
}
a.self-link {
position: absolute;
top: 0;
left: calc(-1 * (3.5rem - 26px));
width: calc(3.5rem - 26px);
height: 2em;
text-align: center;
border: none;
transition: opacity .2s;
opacity: .5;
font-family: sans-serif;
font-weight: normal;
font-size: 83%;
}
a.self-link:hover { opacity: 1; }
a.self-link::before { content: "§"; }
ul > li:before {
content: "\2014";
position: absolute;
margin-left: -1.5em;
}
:target { background-color: #C9FBC9; }
:target .codeblock { background-color: #C9FBC9; }
:target ul { background-color: #C9FBC9; }
.abbr_ref { float: right; }
.folded_abbr_ref { float: right; }
:target .folded_abbr_ref { display: none; }
:target .unfolded_abbr_ref { float: right; display: inherit; }
.unfolded_abbr_ref { display: none; }
.secnum { display: inline-block; min-width: 35pt; }
.header-section-number { display: inline-block; min-width: 35pt; }
.annexnum { display: block; }
div.sourceLinkParent {
float: right;
}
a.sourceLink {
position: absolute;
opacity: 0;
margin-left: 10pt;
}
a.sourceLink:hover {
opacity: 1;
}
a.itemDeclLink {
position: absolute;
font-size: 75%;
text-align: right;
width: 5em;
opacity: 0;
}
a.itemDeclLink:hover { opacity: 1; }
span.marginalizedparent {
position: relative;
left: -5em;
}
li span.marginalizedparent { left: -7em; }
li ul > li span.marginalizedparent { left: -9em; }
li ul > li ul > li span.marginalizedparent { left: -11em; }
li ul > li ul > li ul > li span.marginalizedparent { left: -13em; }
div.footnoteNumberParent {
position: relative;
left: -4.7em;
}
a.marginalized {
position: absolute;
font-size: 75%;
text-align: right;
width: 5em;
}
a.enumerated_item_num {
position: relative;
left: -3.5em;
display: inline-block;
margin-right: -3em;
text-align: right;
width: 3em;
}
div.para { margin-bottom: 0.6em; margin-top: 0.6em; text-align: justify; }
div.section { text-align: justify; }
div.sentence { display: inline; }
span.indexparent {
display: inline;
position: relative;
float: right;
right: -1em;
}
a.index {
position: absolute;
display: none;
}
a.index:before { content: "⟵"; }

a.index:target {
display: inline;
}
.indexitems {
margin-left: 2em;
text-indent: -2em;
}
div.itemdescr {
margin-left: 3em;
}
.bnf {
font-family: serif;
margin-left: 40pt;
margin-top: 0.5em;
margin-bottom: 0.5em;
}
.ncbnf {
font-family: serif;
margin-top: 0.5em;
margin-bottom: 0.5em;
margin-left: 40pt;
}
.ncsimplebnf {
font-family: serif;
font-style: italic;
margin-top: 0.5em;
margin-bottom: 0.5em;
margin-left: 40pt;
background: inherit; 
}
span.textnormal {
font-style: normal;
font-family: serif;
white-space: normal;
display: inline-block;
}
span.rlap {
display: inline-block;
width: 0px;
}
span.descr { font-style: normal; font-family: serif; }
span.grammarterm { font-style: italic; }
span.term { font-style: italic; }
span.terminal { font-family: monospace; font-style: normal; }
span.nonterminal { font-style: italic; }
span.tcode { font-family: monospace; font-style: normal; }
span.textbf { font-weight: bold; }
span.textsc { font-variant: small-caps; }
a.nontermdef { font-style: italic; font-family: serif; }
span.emph { font-style: italic; }
span.techterm { font-style: italic; }
span.mathit { font-style: italic; }
span.mathsf { font-family: sans-serif; }
span.mathrm { font-family: serif; font-style: normal; }
span.textrm { font-family: serif; }
span.textsl { font-style: italic; }
span.mathtt { font-family: monospace; font-style: normal; }
span.mbox { font-family: serif; font-style: normal; }
span.ungap { display: inline-block; width: 2pt; }
span.textit { font-style: italic; }
span.texttt { font-family: monospace; }
span.tcode_in_codeblock { font-family: monospace; font-style: normal; }
span.phantom { color: white; }

span.math { font-style: normal; }
span.mathblock {
display: block;
margin-left: auto;
margin-right: auto;
margin-top: 1.2em;
margin-bottom: 1.2em;
text-align: center;
}
span.mathalpha {
font-style: italic;
}
span.synopsis {
font-weight: bold;
margin-top: 0.5em;
display: block;
}
span.definition {
font-weight: bold;
display: block;
}
.codeblock {
margin-left: 1.2em;
line-height: 127%;
}
.outputblock {
margin-left: 1.2em;
line-height: 127%;
}
div.itemdecl {
margin-top: 2ex;
}
code.itemdeclcode {
white-space: pre;
display: block;
}
span.textsuperscript {
vertical-align: super;
font-size: smaller;
line-height: 0;
}
.footnotenum { vertical-align: super; font-size: smaller; line-height: 0; }
.footnote {
font-size: small;
margin-left: 2em;
margin-right: 2em;
margin-top: 0.6em;
margin-bottom: 0.6em;
}
div.minipage {
display: inline-block;
margin-right: 3em;
}
div.numberedTable {
text-align: center;
margin: 2em;
}
div.figure {
text-align: center;
margin: 2em;
}
table {
border: 1px solid black;
border-collapse: collapse;
margin-left: auto;
margin-right: auto;
margin-top: 0.8em;
text-align: left;
hyphens: none; 
}
td, th {
padding-left: 1em;
padding-right: 1em;
vertical-align: top;
}
td.empty {
padding: 0px;
padding-left: 1px;
}
td.left {
text-align: left;
}
td.right {
text-align: right;
}
td.center {
text-align: center;
}
td.justify {
text-align: justify;
}
td.border {
border-left: 1px solid black;
}
tr.rowsep, td.cline {
border-top: 1px solid black;
}
tr.even, tr.odd {
border-bottom: 1px solid black;
}
tr.capsep {
border-top: 3px solid black;
border-top-style: double;
}
tr.header {
border-bottom: 3px solid black;
border-bottom-style: double;
}
th {
border-bottom: 1px solid black;
}
span.centry {
font-weight: bold;
}
div.table {
display: block;
margin-left: auto;
margin-right: auto;
text-align: center;
width: 90%;
}
span.indented {
display: block;
margin-left: 2em;
margin-bottom: 1em;
margin-top: 1em;
}
ol.enumeratea { list-style-type: none; background: inherit; }
ol.enumerate { list-style-type: none; background: inherit; }

code.sourceCode > span { display: inline; }
</style>
  <style type="text/css">a {
color : #4183C4;
text-decoration: underline;
}
a.marginalized {
text-decoration: none;
}
a.self-link {
text-decoration: none;
}
h1#toctitle {
border-bottom: 1px solid #cccccc;
}
#TOC li {
margin-top: 1px;
margin-bottom: 1px;
}
#TOC ul>li:before { display: none; }
h3.subtitle { margin-top: -15px; }
h1:target { background-color: transparent; }
h2:target { background-color: transparent; }
h3:target { background-color: transparent; }
h4:target { background-color: transparent; }
h5:target { background-color: transparent; }
h6:target { background-color: transparent; }
code span.co { font-family: monospace; }
table tr {
background-color: white;
}
table tr:nth-child(2n) {
background-color: #f6f8fa;
}
#title-block-header > table tr:nth-child(2n) {
background-color: white;
}
td > div.sourceCode {
background-color: inherit;
}
table {
border-collapse: collapse;
}
table td, table th {
border: 1px solid #cccccc;
}
table th {
border-bottom: 1px solid black;
text-align: center;
}
table tr:first-child th {
border-top: 0;
}
table tr:last-child td {
border-bottom: 0;
}
table tr td:first-child,
table tr th:first-child {
border-left: 0;
}
table tr td:last-child,
table tr th:last-child {
border-right: 0;
}
table tbody tr:first-child td {
border-top: 1px solid black;
}
#title-block-header td { border: 0; }
@media all {
body {
margin: 2em;
}
}
@media screen and (min-width: 480px) {
body {
margin: 5em;
}
}
#refs code{padding-left: 0px; text-indent: 0px;}
:root {
--diff-ins: #e6ffed;
--diff-strongins: #acf2bd;
--diff-del: #ffdddd;
--diff-strongdel: #ff8888;
}
span.diffins {
background-color: var(--diff-strongins);
}
span.diffdel {
background-color: var(--diff-strongdel);
}
div.rm { text-decoration: line-through; }
div.rm code.sourceCode { text-decoration: line-through; }
div.addu, span.addu {
color: #006e28;
background-color: var(--diff-ins);
}

div.rm pre, div.add pre { background-color: #f6f8fa; }
div.addu pre { background-color: var(--diff-ins); }
div.add, div.add pre { background-color: var(--diff-ins); }
div.addu blockquote {
border-left: 4px solid #00a000;
padding: 0 15px;
color: #006e28;
text-decoration: none;
}
div.addu blockquote code.sourceCode { text-decoration: none; }
div.addu blockquote pre { text-decoration: none; }
div.addu blockquote pre code { text-decoration: none; }
div.quote {
border-left: 7px solid #ccc;
background: #f9f9f9;
margin: 1.5em 10px;
padding-left: 20px;
}
code.diff span.va { color: #000000; background-color: var(--diff-ins); }
code.diff span.st { color: #000000; background-color: var(--diff-del); }
</style>
  <link href="data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAVoJEAN6CRADegkQAWIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wCCRAAAgkQAAIJEAACCRAAsgkQAvoJEAP+CRAD/gkQA/4JEAP+CRADAgkQALoJEAACCRAAAgkQAAP///wD///8AgkQAAIJEABSCRACSgkQA/IJEAP99PQD/dzMA/3czAP99PQD/gkQA/4JEAPyCRACUgkQAFIJEAAD///8A////AHw+AFiBQwDqgkQA/4BBAP9/PxP/uZd6/9rJtf/bybX/upd7/39AFP+AQQD/gkQA/4FDAOqAQgBc////AP///wDKklv4jlEa/3o7AP+PWC//8+3o///////////////////////z7un/kFox/35AAP+GRwD/mVYA+v///wD///8A0Zpk+NmibP+0d0T/8evj///////+/fv/1sKz/9bCs//9/fr//////+/m2/+NRwL/nloA/5xYAPj///8A////ANKaZPjRmGH/5cKh////////////k149/3UwAP91MQD/lmQ//86rhv+USg3/m1YA/5hSAP+bVgD4////AP///wDSmmT4zpJY/+/bx///////8+TV/8mLT/+TVx//gkIA/5lVAP+VTAD/x6B//7aEVv/JpH7/s39J+P///wD///8A0ppk+M6SWP/u2sf///////Pj1f/Nj1T/2KFs/8mOUv+eWhD/lEsA/8aee/+0glT/x6F7/7J8Rvj///8A////ANKaZPjRmGH/48Cf///////+/v7/2qt//82PVP/OkFX/37KJ/86siv+USg7/mVQA/5hRAP+bVgD4////AP///wDSmmT40ppk/9CVXP/69O////////7+/v/x4M//8d/P//7+/f//////9u7n/6tnJf+XUgD/nFgA+P///wD///8A0ppk+NKaZP/RmWL/1qNy//r07///////////////////////+vXw/9akdP/Wnmn/y5FY/6JfFvj///8A////ANKaZFTSmmTo0ppk/9GYYv/Ql1//5cWm//Hg0P/x4ND/5cWm/9GXYP/RmGH/0ppk/9KaZOjVnmpY////AP///wDSmmQA0ppkEtKaZI7SmmT60ppk/9CWX//OkVb/zpFW/9CWX//SmmT/0ppk/NKaZJDSmmQS0ppkAP///wD///8A0ppkANKaZADSmmQA0ppkKtKaZLrSmmT/0ppk/9KaZP/SmmT/0ppkvNKaZCrSmmQA0ppkANKaZAD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkUtKaZNzSmmTc0ppkVNKaZADSmmQA0ppkANKaZADSmmQA////AP5/AAD4HwAA4AcAAMADAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAMADAADgBwAA+B8AAP5/AAAoAAAAIAAAAEAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wCCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAAyCRACMgkQA6oJEAOqCRACQgkQAEIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wD///8A////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRABigkQA5oJEAP+CRAD/gkQA/4JEAP+CRADqgkQAZoJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAAD///8A////AP///wD///8AgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAA4gkQAwoJEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQAxIJEADyCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAP///wD///8A////AP///wCCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAWgkQAmIJEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAJyCRAAYgkQAAIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wD///8A////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAdIJEAPCCRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAPSCRAB4gkQAAIJEAACCRAAAgkQAAIJEAAD///8A////AP///wD///8AgkQAAIJEAACCRAAAgkQASoJEANKCRAD/gkQA/4JEAP+CRAD/g0YA/39AAP9zLgD/bSQA/2shAP9rIQD/bSQA/3MuAP9/PwD/g0YA/4JEAP+CRAD/gkQA/4JEAP+CRADUgkQAToJEAACCRAAAgkQAAP///wD///8A////AP///wB+PwAAgkUAIoJEAKiCRAD/gkQA/4JEAP+CRAD/hEcA/4BBAP9sIwD/dTAA/5RfKv+viF7/vp56/76ee/+wiF7/lWAr/3YxAP9sIwD/f0AA/4RHAP+CRAD/gkQA/4JEAP+CRAD/gkQArIJEACaBQwAA////AP///wD///8A////AIBCAEBzNAD6f0EA/4NFAP+CRAD/gkQA/4VIAP92MwD/bSUA/6N1Tv/ezsL/////////////////////////////////38/D/6V3Uv9uJgD/dTEA/4VJAP+CRAD/gkQA/4JEAP+BQwD/fUAA/4FDAEj///8A////AP///wD///8AzJRd5qBlKf91NgD/dDUA/4JEAP+FSQD/cy4A/3YyAP/PuKP//////////////////////////////////////////////////////9K7qP94NQD/ciwA/4VJAP+CRAD/fkEA/35BAP+LSwD/mlYA6v///wD///8A////AP///wDdpnL/4qx3/8KJUv+PUhf/cTMA/3AsAP90LgD/4dK+/////////////////////////////////////////////////////////////////+TYxf91MAD/dTIA/31CAP+GRwD/llQA/6FcAP+gWwD8////AP///wD///8A////ANGZY/LSm2X/4ap3/92mcP+wdT3/byQA/8mwj////////////////////////////////////////////////////////////////////////////+LYxv9zLgP/jUoA/59bAP+hXAD/nFgA/5xYAPL///8A////AP///wD///8A0ppk8tKaZP/RmWL/1p9q/9ubXv/XqXj////////////////////////////7+fD/vZyG/6BxS/+gcUr/vJuE//r37f//////////////////////3MOr/5dQBf+dVQD/nVkA/5xYAP+cWAD/nFgA8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/SmWP/yohJ//jo2P//////////////////////4NTG/4JDFf9lGAD/bSQA/20kAP9kGAD/fz8S/+Xb0f//////5NG9/6txN/+LOgD/m1QA/51aAP+cWAD/m1cA/5xYAP+cWADy////AP///wD///8A////ANKaZPLSmmT/0ppk/8+TWf/Unmv//v37//////////////////////+TWRr/VwsA/35AAP+ERgD/g0UA/4JGAP9lHgD/kFga/8KXX/+TRwD/jT4A/49CAP+VTQD/n10A/5xYAP+OQQD/lk4A/55cAPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/y4tO/92yiP//////////////////////8NnE/8eCQP+rcTT/ez0A/3IyAP98PgD/gEMA/5FSAP+USwD/jj8A/5lUAP+JNwD/yqV2/694Mf+HNQD/jkAA/82rf/+laBj/jT4A8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/LiUr/4byY///////////////////////gupX/0I5P/+Wuev/Lklz/l1sj/308AP+QSwD/ol0A/59aAP+aVQD/k0oA/8yoh///////+fXv/6pwO//Lp3v///////Pr4f+oay7y////AP///wD///8A////ANKaZPLSmmT/0ppk/8uJSv/hvJj//////////////////////+G7l//Jhkb/0ppk/96nc//fqXX/x4xO/6dkFP+QSQD/llEA/5xXAP+USgD/yaOA///////38uv/qG05/8ijdv//////8efb/6ZpLPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/zIxO/9yxh///////////////////////7dbA/8iEQf/Sm2X/0Zlj/9ScZv/eqHf/2KJv/7yAQf+XTgD/iToA/5lSAP+JNgD/yKFv/611LP+HNQD/jT8A/8qmeP+kZRT/jT4A8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/Pk1n/1J5q//78+//////////////////+/fv/1aFv/8iEQv/Tm2b/0ppl/9GZY//Wn2z/1pZc/9eldf/Bl2b/kUcA/4w9AP+OQAD/lUwA/59eAP+cWQD/jT8A/5ZOAP+eXADy////AP///wD///8A////ANKaZPLSmmT/0ppk/9KZY//KiEn/8d/P///////////////////////47+f/05tm/8iCP//KiEj/yohJ/8eCP//RmGH//vfy///////n1sP/rXQ7/4k4AP+TTAD/nVoA/5xYAP+cVwD/nFgA/5xYAPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/0ptl/8uLTf/aq37////////////////////////////+/fz/6c2y/961jv/etY7/6Myx//78+v//////////////////////3MWv/5xXD/+ORAD/mFQA/51ZAP+cWAD/nFgA8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/SmmT/0ppk/8mFRP/s1b//////////////////////////////////////////////////////////////////////////////+PD/0JFU/7NzMv+WUQD/kUsA/5tXAP+dWQDy////AP///wD///8A////ANKaZP/SmmT/0ppk/9KaZP/Sm2X/z5NZ/8yMT//z5NX/////////////////////////////////////////////////////////////////9Ofa/8yNUP/UmGH/36p5/8yTWv+qaSD/kksA/5ROAPz///8A////AP///wD///8A0ppk5NKaZP/SmmT/0ppk/9KaZP/TnGf/zY9T/82OUv/t1sD//////////////////////////////////////////////////////+7Yw//OkFX/zI5R/9OcZ//SmmP/26V0/9ymdf/BhUf/ol8R6P///wD///8A////AP///wDSmmQ80ppk9tKaZP/SmmT/0ppk/9KaZP/TnGj/zpFW/8qJSv/dson/8uHS//////////////////////////////////Lj0//etIv/y4lL/86QVf/TnGj/0ppk/9KaZP/RmWP/05xn/9ymdfjUnWdC////AP///wD///8A////ANKaZADSmmQc0ppkotKaZP/SmmT/0ppk/9KaZP/Tm2b/0Zli/8qJSf/NjlH/16Z3/+G8mP/myKr/5siq/+G8mP/Xp3f/zY5S/8qISf/RmGH/05tm/9KaZP/SmmT/0ppk/9KaZP/SmmSm0pljINWdaQD///8A////AP///wD///8A0ppkANKaZADSmmQA0ppkQtKaZMrSmmT/0ppk/9KaZP/SmmT/0ptl/9GYYf/Nj1P/y4lL/8qISP/KiEj/y4lK/82PU//RmGH/0ptl/9KaZP/SmmT/0ppk/9KaZP/SmmTO0ppkRtKaZADSmmQA0ppkAP///wD///8A////AP///wDSmmQA0ppkANKaZADSmmQA0ppkANKaZGzSmmTu0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmTw0ppkcNKaZADSmmQA0ppkANKaZADSmmQA////AP///wD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZBLSmmSQ0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppklNKaZBTSmmQA0ppkANKaZADSmmQA0ppkANKaZAD///8A////AP///wD///8A0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQy0ppkutKaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppkvtKaZDbSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkAP///wD///8A////AP///wDSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkXNKaZODSmmT/0ppk/9KaZP/SmmT/0ppk5NKaZGDSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA////AP///wD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkBtKaZIbSmmTo0ppk6tKaZIrSmmQK0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZAD///8A////AP/8P///+B///+AH//+AAf//AAD//AAAP/AAAA/gAAAHwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA+AAAAfwAAAP/AAAP/8AAP//gAH//+AH///4H////D//" rel="icon" />
  <!--[if lt IE 9]>
    <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
  <![endif]-->
  
</head>
<body>
<div class="wrapper">
<header id="title-block-header">
<h1 class="title" style="text-align:center">Designated-initializers for Base Classes</h1>

<table style="border:none;float:right">
  <tr>
    <td>Document #:</td>
    <td>P2287R2</td>
  </tr>
  <tr>
    <td>Date:</td>
    <td>2023-03-12</td>
  </tr>
  <tr>
    <td style="vertical-align:top">Project:</td>
    <td>Programming Language C++</td>
  </tr>
  <tr>
    <td style="vertical-align:top">Audience:</td>
    <td>
      EWG<br>
    </td>
  </tr>
  <tr>
    <td style="vertical-align:top">Reply-to:</td>
    <td>
      Barry Revzin<br>&lt;<a href="mailto:barry.revzin@gmail.com" class="email">barry.revzin@gmail.com</a>&gt;<br>
    </td>
  </tr>
</table>

</header>
<div style="clear:both">
<div id="TOC" role="doc-toc">
<h1 id="toctitle">Contents</h1>
<ul>
<li><a href="#revision-history"><span class="toc-section-number">1</span> Revision History<span></span></a></li>
<li><a href="#introduction"><span class="toc-section-number">2</span> Introduction<span></span></a></li>
<li><a href="#proposal"><span class="toc-section-number">3</span> Proposal<span></span></a>
<ul>
<li><a href="#naming-the-base-classes"><span class="toc-section-number">3.1</span> Naming the base classes<span></span></a></li>
<li><a href="#naming-all-the-subobjects"><span class="toc-section-number">3.2</span> Naming all the subobjects<span></span></a></li>
<li><a href="#impact-on-existing-code"><span class="toc-section-number">3.3</span> Impact on Existing Code<span></span></a></li>
</ul></li>
<li><a href="#wording"><span class="toc-section-number">4</span> Wording<span></span></a>
<ul>
<li><a href="#strategy"><span class="toc-section-number">4.1</span> Strategy<span></span></a></li>
<li><a href="#actual-wording"><span class="toc-section-number">4.2</span> Actual Wording<span></span></a></li>
<li><a href="#feature-test-macro"><span class="toc-section-number">4.3</span> Feature-test Macro<span></span></a></li>
</ul></li>
<li><a href="#acknowledgements"><span class="toc-section-number">5</span> Acknowledgements<span></span></a></li>
<li><a href="#bibliography"><span class="toc-section-number">6</span> References<span></span></a></li>
</ul>
</div>
<h1 data-number="1" style="border-bottom:1px solid #cccccc" id="revision-history"><span class="header-section-number">1</span> Revision History<a href="#revision-history" class="self-link"></a></h1>
<p><span class="citation" data-cites="P2287R1">[<a href="#ref-P2287R1" role="doc-biblioref">P2287R1</a>]</span> proposed a novel way of naming base classes, as well as a way for naming indirect non-static data members. This revision <em>only</em> supports naming direct or indirect non-static data members, with no mechanism to name base classes. Basically only what Matthias suggested.</p>
<p><span class="citation" data-cites="P2287R0">[<a href="#ref-P2287R0" role="doc-biblioref">P2287R0</a>]</span> proposed a single syntax for a <em>designated-initializer</em> that identifies a base class. Based on a reflector suggestion from Matthias Stearn, this revision extends the syntax to allow the brace-elision version of <em>designated-initializer</em>: allow naming indirect non-static data members as well. Also actually correctly targeting EWG this time.</p>
<h1 data-number="2" style="border-bottom:1px solid #cccccc" id="introduction"><span class="header-section-number">2</span> Introduction<a href="#introduction" class="self-link"></a></h1>
<p><span class="citation" data-cites="P0017R1">[<a href="#ref-P0017R1" role="doc-biblioref">P0017R1</a>]</span> extended aggregates to allow an aggregate to have a base class. <span class="citation" data-cites="P0329R4">[<a href="#ref-P0329R4" role="doc-biblioref">P0329R4</a>]</span> gave us designated initializers, which allow for much more expressive and functional initialization of aggregates. However, the two do not mix: a designated initializer can currently only refer to a direct non-static data members. This means that if I have a type like:</p>
<blockquote>
<div class="sourceCode" id="cb1"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb1-1"><a href="#cb1-1"></a><span class="kw">struct</span> A <span class="op">{</span></span>
<span id="cb1-2"><a href="#cb1-2"></a>    <span class="dt">int</span> a;</span>
<span id="cb1-3"><a href="#cb1-3"></a><span class="op">}</span>;</span>
<span id="cb1-4"><a href="#cb1-4"></a></span>
<span id="cb1-5"><a href="#cb1-5"></a><span class="kw">struct</span> B <span class="op">:</span> A <span class="op">{</span></span>
<span id="cb1-6"><a href="#cb1-6"></a>    <span class="dt">int</span> b;</span>
<span id="cb1-7"><a href="#cb1-7"></a><span class="op">}</span>;</span></code></pre></div>
</blockquote>
<p>While I can initialize an <code class="sourceCode cpp">A</code> like <code class="sourceCode cpp">A<span class="op">{.</span>a<span class="op">=</span><span class="dv">1</span><span class="op">}</span></code>, I cannot designated-initialize <code class="sourceCode cpp">B</code>. An attempt like <code class="sourceCode cpp">B<span class="op">{</span>{1}, <span class="op">.</span>b<span class="op">=</span><span class="dv">2</span><span class="op">}</span></code> runs afoul of the rule that the initializers must either be all designated or none designated. But there is currently no way to designate the base class here.</p>
<p>Which means that my only options for initializing a <code class="sourceCode cpp">B</code> are to fall-back to regular aggregate initialization and write either <code class="sourceCode cpp">B<span class="op">{</span>{1}, <span class="dv">2</span><span class="op">}</span></code> or <code class="sourceCode cpp">B<span class="op">{</span><span class="dv">1</span>, <span class="dv">2</span><span class="op">}</span></code>. Neither are especially satisfactory.</p>
<h1 data-number="3" style="border-bottom:1px solid #cccccc" id="proposal"><span class="header-section-number">3</span> Proposal<a href="#proposal" class="self-link"></a></h1>
<p>This paper proposes extending designated initialization syntax to include both the ability to name base classes and also the ability to name base class members. In short, based on the above declarations of <code class="sourceCode cpp">A</code> and <code class="sourceCode cpp">B</code>, this proposal allows all of the following declarations:</p>
<blockquote>
<div class="sourceCode" id="cb2"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb2-1"><a href="#cb2-1"></a>B<span class="op">{</span>{1}, <span class="dv">2</span><span class="op">}</span>         <span class="co">// already valid in C++17</span></span>
<span id="cb2-2"><a href="#cb2-2"></a>B<span class="op">{</span><span class="dv">1</span>, <span class="dv">2</span><span class="op">}</span>           <span class="co">// already valid in C++17</span></span>
<span id="cb2-3"><a href="#cb2-3"></a></span>
<span id="cb2-4"><a href="#cb2-4"></a>B<span class="op">{.</span>a<span class="op">=</span><span class="dv">1</span>, <span class="op">.</span>b<span class="op">=</span><span class="dv">2</span><span class="op">}</span>     <span class="co">// proposed</span></span>
<span id="cb2-5"><a href="#cb2-5"></a>B<span class="op">{.</span>a<span class="op">{</span><span class="dv">1</span><span class="op">}</span>, <span class="op">.</span>b{2}<span class="op">}</span>   <span class="co">// proposed</span></span>
<span id="cb2-6"><a href="#cb2-6"></a>B<span class="op">{.</span>b<span class="op">=</span><span class="dv">2</span>, <span class="op">.</span>a<span class="op">=</span><span class="dv">1</span><span class="op">}</span>     <span class="co">// still ill-formed</span></span></code></pre></div>
</blockquote>
<h2 data-number="3.1" id="naming-the-base-classes"><span class="header-section-number">3.1</span> Naming the base classes<a href="#naming-the-base-classes" class="self-link"></a></h2>
<p>THe original revisions of this paper dealt with how to name the <code class="sourceCode cpp">A</code> base class of <code class="sourceCode cpp">B</code>, and what this means for more complicated base classes (such at those with template parameters). This revision eschews that approach entirely: it’s simpler to just stick with naming members, direct and indirect. After all, that’s how these aggregates will be interacted with.</p>
<p>What this means is that while this paper proposes that this works:</p>
<blockquote>
<div class="sourceCode" id="cb3"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb3-1"><a href="#cb3-1"></a><span class="kw">struct</span> A <span class="op">{</span> <span class="dt">int</span> a; <span class="op">}</span>;</span>
<span id="cb3-2"><a href="#cb3-2"></a><span class="kw">struct</span> B <span class="op">:</span> A <span class="op">{</span> <span class="dt">int</span> b; <span class="op">}</span>;</span>
<span id="cb3-3"><a href="#cb3-3"></a></span>
<span id="cb3-4"><a href="#cb3-4"></a><span class="kw">auto</span> b <span class="op">=</span> B<span class="op">{.</span>a<span class="op">=</span><span class="dv">1</span>, <span class="op">.</span>b<span class="op">=</span><span class="dv">2</span><span class="op">}</span>;</span></code></pre></div>
</blockquote>
<p>There would be no way to designated-initialize a type like this:</p>
<blockquote>
<div class="sourceCode" id="cb4"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb4-1"><a href="#cb4-1"></a><span class="kw">struct</span> C <span class="op">:</span> std<span class="op">::</span>string <span class="op">{</span> <span class="dt">int</span> c; <span class="op">}</span>;</span></code></pre></div>
</blockquote>
<p>Because there would be no way to designated-initialize the base <code class="sourceCode cpp">std<span class="op">::</span>string</code> suboject.</p>
<p>Likewise, there would be no way to designated-initialize both of the <code class="sourceCode cpp">x</code> subobjects in this example:</p>
<blockquote>
<div class="sourceCode" id="cb5"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb5-1"><a href="#cb5-1"></a><span class="kw">struct</span> D <span class="op">{</span> <span class="dt">int</span> x; <span class="op">}</span>;</span>
<span id="cb5-2"><a href="#cb5-2"></a><span class="kw">struct</span> E <span class="op">:</span> D <span class="op">{</span> <span class="dt">int</span> x; <span class="op">}</span>;</span>
<span id="cb5-3"><a href="#cb5-3"></a></span>
<span id="cb5-4"><a href="#cb5-4"></a><span class="kw">auto</span> e <span class="op">=</span> E<span class="op">{.</span>x<span class="op">=</span><span class="dv">1</span><span class="op">}</span>; <span class="co">// initializes E::x, not D::x</span></span></code></pre></div>
</blockquote>
<p>However, even without the inability to perfectly initialize objects of types <code class="sourceCode cpp">C</code> and <code class="sourceCode cpp">E</code> here, it is still quite beneficial to initialize objects of type <code class="sourceCode cpp">B</code> - and this is still the pretty typical case for aggregates with base classes: those base classes are also aggregates.</p>
<p>Coming up with a way to <em>name</em> the base class subobject of a class seems useful, but that’s largely orthogonal. It can be done later.</p>
<h2 data-number="3.2" id="naming-all-the-subobjects"><span class="header-section-number">3.2</span> Naming all the subobjects<a href="#naming-all-the-subobjects" class="self-link"></a></h2>
<p>The current wording we have says that, from <span>9.4.2 <a href="https://wg21.link/dcl.init.aggr">[dcl.init.aggr]</a></span>/3.1:</p>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_1" id="pnum_1">(3.1)</a></span> If the initializer list is a brace-enclosed <em>designated-initializer-list</em>, the aggregate shall be of class type, the <em>identifier</em> in each designator shall name a direct non-static data member of the class […]</p>
</blockquote>
<p>And, from <span>9.4.5 <a href="https://wg21.link/dcl.init.list">[dcl.init.list]</a></span>/3.1 (conveniently, it’s 3.1 in both cases):</p>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_2" id="pnum_2">(3.1)</a></span> If the <em>braced-init-list</em> contains a <em>designated-initializer-list</em>, <code class="sourceCode cpp">T</code> shall be an aggregate class. The ordered identifiers in the designators of the <em>designated-initializer-list</em> shall form a subsequence of the ordered identifiers in the direct non-static data members of <code class="sourceCode cpp">T</code>. Aggregate initialization is performed ([dcl.init.aggr]).</p>
</blockquote>
<p>The proposal here is to extend both of these rules to cover not just the direct non-static data members of <code class="sourceCode cpp">T</code> but also all indirect members, such that every interleaving base class is also an aggregate class. That is:</p>
<blockquote>
<div class="sourceCode" id="cb6"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb6-1"><a href="#cb6-1"></a><span class="kw">struct</span> A <span class="op">{</span> <span class="dt">int</span> a; <span class="op">}</span>;</span>
<span id="cb6-2"><a href="#cb6-2"></a><span class="kw">struct</span> B <span class="op">:</span> A <span class="op">{</span> <span class="dt">int</span> b; <span class="op">}</span>;</span>
<span id="cb6-3"><a href="#cb6-3"></a><span class="kw">struct</span> C <span class="op">:</span> A <span class="op">{</span> C<span class="op">()</span>; <span class="dt">int</span> c; <span class="op">}</span>;</span>
<span id="cb6-4"><a href="#cb6-4"></a><span class="kw">struct</span> D <span class="op">:</span> C <span class="op">{</span> <span class="dt">int</span> d; <span class="op">}</span>;</span>
<span id="cb6-5"><a href="#cb6-5"></a></span>
<span id="cb6-6"><a href="#cb6-6"></a>A<span class="op">{.</span>a<span class="op">=</span><span class="dv">1</span><span class="op">}</span>;       <span class="co">// okay since C++17</span></span>
<span id="cb6-7"><a href="#cb6-7"></a>B<span class="op">{.</span>a<span class="op">=</span><span class="dv">1</span>, <span class="op">.</span>b<span class="op">=</span><span class="dv">2</span><span class="op">}</span>; <span class="co">// proposed okay, &#39;a&#39; is a direct member of an aggregate class</span></span>
<span id="cb6-8"><a href="#cb6-8"></a>               <span class="co">// and A is a direct base</span></span>
<span id="cb6-9"><a href="#cb6-9"></a>C<span class="op">{.</span>c<span class="op">=</span><span class="dv">1</span><span class="op">}</span>;       <span class="co">// error: C is not an aggregate</span></span>
<span id="cb6-10"><a href="#cb6-10"></a>D<span class="op">{.</span>a<span class="op">=</span><span class="dv">1</span><span class="op">}</span>;       <span class="co">// error: &#39;a&#39; is a direct member of an aggregate class</span></span>
<span id="cb6-11"><a href="#cb6-11"></a>               <span class="co">// but an intermediate base class (C) is not an aggregate</span></span></code></pre></div>
</blockquote>
<p>Or, put differently, every identifier shall name a non-static data member that is not a (direct or indirect) member of any base class that is not an aggregate.</p>
<p>Also this is still based on lookup rules, so if the same name appears in multiple base classes, then either it’s only the most derived one that counts:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb7-1"><a href="#cb7-1"></a><span class="kw">struct</span> X <span class="op">{</span> <span class="dt">int</span> x; <span class="op">}</span>;</span>
<span id="cb7-2"><a href="#cb7-2"></a><span class="kw">struct</span> Y <span class="op">:</span> X <span class="op">{</span> <span class="dt">int</span> x; <span class="op">}</span>;</span>
<span id="cb7-3"><a href="#cb7-3"></a>Y<span class="op">{.</span>x<span class="op">=</span><span class="dv">1</span><span class="op">}</span>; <span class="co">// initializes Y::x</span></span></code></pre></div>
<p>or is ambiguous:</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb8-1"><a href="#cb8-1"></a><span class="kw">struct</span> X <span class="op">{</span> <span class="dt">int</span> x; <span class="op">}</span>;</span>
<span id="cb8-2"><a href="#cb8-2"></a><span class="kw">struct</span> Y <span class="op">{</span> <span class="dt">int</span> x; <span class="op">}</span>;</span>
<span id="cb8-3"><a href="#cb8-3"></a><span class="kw">struct</span> Z <span class="op">:</span> X, Y <span class="op">{</span> <span class="op">}</span>;</span>
<span id="cb8-4"><a href="#cb8-4"></a>Z<span class="op">{.</span>x<span class="op">=</span><span class="dv">1</span><span class="op">}</span>; <span class="co">// error:: ambiguous which X</span></span></code></pre></div>
<p>would be ill-formed on the basis that <code class="sourceCode cpp">Z<span class="op">::</span>x</code> is ambiguous.</p>
<h2 data-number="3.3" id="impact-on-existing-code"><span class="header-section-number">3.3</span> Impact on Existing Code<a href="#impact-on-existing-code" class="self-link"></a></h2>
<p>There is one case I can think of where code would change meaning:</p>
<blockquote>
<div class="sourceCode" id="cb9"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb9-1"><a href="#cb9-1"></a><span class="kw">struct</span> A <span class="op">{</span> <span class="dt">int</span> a; <span class="op">}</span>;</span>
<span id="cb9-2"><a href="#cb9-2"></a><span class="kw">struct</span> B <span class="op">:</span> A <span class="op">{</span> <span class="dt">int</span> b; <span class="op">}</span>;</span>
<span id="cb9-3"><a href="#cb9-3"></a></span>
<span id="cb9-4"><a href="#cb9-4"></a><span class="dt">void</span> f<span class="op">(</span>A<span class="op">)</span>; <span class="co">// #1</span></span>
<span id="cb9-5"><a href="#cb9-5"></a><span class="dt">void</span> f<span class="op">(</span>B<span class="op">)</span>; <span class="co">// #2</span></span>
<span id="cb9-6"><a href="#cb9-6"></a></span>
<span id="cb9-7"><a href="#cb9-7"></a><span class="dt">void</span> g<span class="op">()</span> <span class="op">{</span></span>
<span id="cb9-8"><a href="#cb9-8"></a>    f<span class="op">({.</span>a<span class="op">=</span><span class="dv">1</span><span class="op">})</span>;</span>
<span id="cb9-9"><a href="#cb9-9"></a><span class="op">}</span></span></code></pre></div>
</blockquote>
<p>In C++23, <code class="sourceCode cpp">f<span class="op">({.</span>a<span class="op">=</span><span class="dv">1</span><span class="op">})</span></code> calls <code class="sourceCode cpp"><span class="pp">#1</span></code>, as it’s the only viable candidate. But with this change, <code class="sourceCode cpp"><span class="pp">#2</span></code> also becomes a viable candidate, so this call becomes ambiguous. I have no idea how much such code exists. This is, at least, easy to fix.</p>
<p>I don’t think there’s a case where code would change from one valid meaning to a different valid meaning - just from valid to ambiguous.</p>
<h1 data-number="4" style="border-bottom:1px solid #cccccc" id="wording"><span class="header-section-number">4</span> Wording<a href="#wording" class="self-link"></a></h1>
<h2 data-number="4.1" id="strategy"><span class="header-section-number">4.1</span> Strategy<a href="#strategy" class="self-link"></a></h2>
<p>The wording strategy here is as follows. Let’s say we have this simple case:</p>
<blockquote>
<div class="sourceCode" id="cb10"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb10-1"><a href="#cb10-1"></a><span class="kw">struct</span> A <span class="op">{</span> <span class="dt">int</span> a; <span class="op">}</span>;</span>
<span id="cb10-2"><a href="#cb10-2"></a><span class="kw">struct</span> B <span class="op">:</span> A <span class="op">{</span> <span class="dt">int</span> b; <span class="op">}</span>;</span></code></pre></div>
</blockquote>
<p>In the current wording, <code class="sourceCode cpp">B</code> has two elements (the <code class="sourceCode cpp">A</code> direct base class and then the <code class="sourceCode cpp">b</code> member). The initialization <code class="sourceCode cpp">B<span class="op">{.</span>b<span class="op">=</span><span class="dv">2</span><span class="op">}</span></code> is considered to have one explicitly initialized element (the <code class="sourceCode cpp">b</code>, initialized with <code class="sourceCode cpp"><span class="dv">2</span></code>) and then the <code class="sourceCode cpp">A</code> is not explicitly initialized and cannot have a default member initializer, so it is copy-initialized from <code class="sourceCode cpp"><span class="op">{}</span></code>.</p>
<p>The strategy to handle <code class="sourceCode cpp">B<span class="op">{.</span>a<span class="op">=</span><span class="dv">1</span>, <span class="op">.</span>b<span class="op">=</span><span class="dv">2</span><span class="op">}</span></code> is to group the indirect non-static data members under their corresponding direct base class and to treat those base class elements as being explicitly initialized. So here, the <code class="sourceCode cpp">A</code> element is explicitly initialized from <code class="sourceCode cpp"><span class="op">{.</span>a<span class="op">=</span><span class="dv">1</span><span class="op">}</span></code> and the <code class="sourceCode cpp">b</code> element continues to be explicitly initialized from <code class="sourceCode cpp"><span class="dv">2</span></code>. And then this applies recursively, so given:</p>
<blockquote>
<div class="sourceCode" id="cb11"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb11-1"><a href="#cb11-1"></a><span class="kw">struct</span> C <span class="op">:</span> B <span class="op">{</span> <span class="dt">int</span> c; <span class="op">}</span>;</span></code></pre></div>
</blockquote>
<p>With <code class="sourceCode cpp">C<span class="op">{.</span>a<span class="op">=</span><span class="dv">1</span>, <span class="op">.</span>c<span class="op">=</span><span class="dv">2</span><span class="op">}</span></code>, we have:</p>
<ul>
<li>the <code class="sourceCode cpp">B</code> element is explicitly initialized from <code class="sourceCode cpp"><span class="op">{.</span>a<span class="op">=</span><span class="dv">1</span><span class="op">}</span></code>, which leads to:
<ul>
<li>the <code class="sourceCode cpp">A</code> element is explicitly initialized from <code class="sourceCode cpp"><span class="op">{.</span>a<span class="op">=</span><span class="dv">1</span><span class="op">}</span></code>, which leads to:
<ul>
<li>the <code class="sourceCode cpp">a</code> element is explicitly initialized from <code class="sourceCode cpp"><span class="dv">1</span></code></li>
</ul></li>
<li>the <code class="sourceCode cpp">b</code> element is not explicitly initialized and has no default member initializer, so it is copy-initialized from <code class="sourceCode cpp"><span class="op">{}</span></code></li>
</ul></li>
<li>the <code class="sourceCode cpp">c</code> element is explicitly initialized from <code class="sourceCode cpp"><span class="dv">2</span></code></li>
</ul>
<h2 data-number="4.2" id="actual-wording"><span class="header-section-number">4.2</span> Actual Wording<a href="#actual-wording" class="self-link"></a></h2>
<p>Extend <span>9.4.2 <a href="https://wg21.link/dcl.init.aggr">[dcl.init.aggr]</a></span>/3.1:</p>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_3" id="pnum_3">(3.1)</a></span> If the initializer list is a brace-enclosed <em>designated-initializer-list</em>, <span class="addu">then</span> the aggregate shall be of class type<span class="rm" style="color: #bf0303"><del>,</del></span> <span class="addu">and</span> the <em>identifier</em> in each <em>designator</em> shall name a <span class="rm" style="color: #bf0303"><del>direct non-static data member</del></span> <span class="addu">designatable member ([dcl.init.list])</span> of the class<span class="addu">.</span> <span class="rm" style="color: #bf0303"><del>, and the</del></span> <span class="addu">The</span> explicitly initialized elements of the aggregate are the elements that are, or contain <span class="addu">(in the case of a member of an anonymous union or of a base class)</span>, those members.</p>
</blockquote>
<p>And extend <span>9.4.2 <a href="https://wg21.link/dcl.init.aggr">[dcl.init.aggr]</a></span>/4 to cover base class elements:</p>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_4" id="pnum_4">4</a></span> For each explicitly initialized element:</p>
<div class="addu">
<ul>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_5" id="pnum_5">(4.0)</a></span> If the initializer list is a brace-enclosed <em>designated-initializer-list</em> and the element is a direct base class, then let <code class="sourceCode cpp">C</code> denote that direct base class and let <code class="sourceCode cpp">T</code> denote the class. The element is initialized from a synthesized brace-enclosed <em>designated-initializer-list</em> containing each <em>designator</em> for which lookup in <code class="sourceCode cpp">T</code> names a direct or indirect non-static data member of <code class="sourceCode cpp">C</code> in the same order as in the original <em>designated-initializer-list</em>.</li>
</ul>
<blockquote>
<p>[<em>Example</em></p>
<div class="sourceCode" id="cb12"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb12-1"><a href="#cb12-1"></a>struct A { int a; };</span>
<span id="cb12-2"><a href="#cb12-2"></a>struct B : A { int b; };</span>
<span id="cb12-3"><a href="#cb12-3"></a>struct C : B { int c; };</span>
<span id="cb12-4"><a href="#cb12-4"></a></span>
<span id="cb12-5"><a href="#cb12-5"></a>// the A element is intialized from {.a=1}</span>
<span id="cb12-6"><a href="#cb12-6"></a>B x = B{.a=1};</span>
<span id="cb12-7"><a href="#cb12-7"></a></span>
<span id="cb12-8"><a href="#cb12-8"></a>// the B element is initialized from {.a=2, .b=3}</span>
<span id="cb12-9"><a href="#cb12-9"></a>// which leads to its A element being initialized from {.a=2}</span>
<span id="cb12-10"><a href="#cb12-10"></a>C y = C{.a=2, .b=3, .c=4};</span>
<span id="cb12-11"><a href="#cb12-11"></a></span>
<span id="cb12-12"><a href="#cb12-12"></a>struct A2 : A { int a; };</span>
<span id="cb12-13"><a href="#cb12-13"></a></span>
<span id="cb12-14"><a href="#cb12-14"></a>// the A element is not explicitly initialized</span>
<span id="cb12-15"><a href="#cb12-15"></a>A2 z = {.a=1};</span></code></pre></div>
<p><em>-end example</em>]</p>
</blockquote>
</div>
<ul>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_6" id="pnum_6">(4.1)</a></span> <span class="rm" style="color: #bf0303"><del>If</del></span> <span class="addu">Otherwise, if</span> the element is an anonymous union […]</li>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_7" id="pnum_7">(4.2)</a></span> Otherwise, the element is copy-initialized from the corresponding <em>initializer-clause</em> or is initialized with the <em>brace-or-equal-initializer</em> of the corresponding <em>designated-initializer-clause</em>. […]</li>
</ul>
</blockquote>
<p>Extend <span>9.4.5 <a href="https://wg21.link/dcl.init.list">[dcl.init.list]</a></span>/3.1:</p>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_8" id="pnum_8">(3.1)</a></span> If the <em>braced-init-list</em> contains a <em>designated-initializer-list</em>, <code class="sourceCode cpp">T</code> shall be an aggregate class. The ordered <em>identifier</em>s in the designators of the <em>designated-initializer-list</em> shall form a subsequence of <span class="addu"><em>designatable members</em> of <code class="sourceCode cpp">T</code>, defined as follows:</span> <span class="rm" style="color: #bf0303"><del>the ordered <em>identifier</em>s in the direct non-static data members of <span><code class="sourceCode default">T</code></span>.</del></span></p>
<div class="addu">
<ul>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_9" id="pnum_9">(3.1.1)</a></span> For each direct base class <code class="sourceCode cpp">C</code> of <code class="sourceCode cpp">T</code> that is an aggregate class, the designatable members of <code class="sourceCode cpp">C</code> for which lookup for that member in <code class="sourceCode cpp">T</code> finds the member of <code class="sourceCode cpp">C</code>,</li>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_10" id="pnum_10">(3.1.2)</a></span> The ordered <em>identifiers</em> in the direct non-static members of <code class="sourceCode cpp">T</code>.</li>
</ul>
</div>
<p>Aggregate initialization is performed ([dcl.init.aggr]). [<em>Example 2</em>:</p>
<div>
<div class="sourceCode" id="cb13"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb13-1"><a href="#cb13-1"></a>    struct A { int x; int y; int z; };</span>
<span id="cb13-2"><a href="#cb13-2"></a>    A a{.y = 2, .x = 1};                // error: designator order does not match declaration order</span>
<span id="cb13-3"><a href="#cb13-3"></a>    A b{.x = 1, .z = 2};                // OK, b.y initialized to 0</span>
<span id="cb13-4"><a href="#cb13-4"></a></span>
<span id="cb13-5"><a href="#cb13-5"></a><span class="va">+   struct B : A { int q; };</span></span>
<span id="cb13-6"><a href="#cb13-6"></a><span class="va">+   B e{.x = 1, .q = 3};                // OK, e.y and e.z initialized to 0</span></span>
<span id="cb13-7"><a href="#cb13-7"></a><span class="va">+   B f{.q = 3, .x = 1};                // error: designator order does not match declaration order</span></span>
<span id="cb13-8"><a href="#cb13-8"></a></span>
<span id="cb13-9"><a href="#cb13-9"></a><span class="va">+   struct C { int p; int x; };</span></span>
<span id="cb13-10"><a href="#cb13-10"></a><span class="va">+   struct D : A, C { };</span></span>
<span id="cb13-11"><a href="#cb13-11"></a><span class="va">+   D g{.y=1, .p=2};                    // OK</span></span>
<span id="cb13-12"><a href="#cb13-12"></a><span class="va">+   D h{.x=2};                          // error: x is not a designatable member</span></span>
<span id="cb13-13"><a href="#cb13-13"></a></span>
<span id="cb13-14"><a href="#cb13-14"></a><span class="va">+   struct NonAggr { int na; NonAggr(int); };</span></span>
<span id="cb13-15"><a href="#cb13-15"></a><span class="va">+   struct E : NonAggr { int e; };</span></span>
<span id="cb13-16"><a href="#cb13-16"></a><span class="va">+   E i{.na=1, .e=2};                   // error: na is not a designatable member</span></span></code></pre></div>
</div>
<p>— <em>end example</em>]</p>
</blockquote>
<p>Add an Annex C entry:</p>
<div class="addu">
<blockquote>
<p><strong>Affected sublcause</strong>: [dcl.init] <br /> <strong>Change</strong>: Support for designated initialization of base classes of aggregates. <br /> <strong>Rationale</strong>: New functionality. <br /> <strong>Effect on original feature</strong>: Some valid C++23 code may fail to compile. For example:</p>
<div class="sourceCode" id="cb14"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb14-1"><a href="#cb14-1"></a>struct A { int a; };</span>
<span id="cb14-2"><a href="#cb14-2"></a>struct B : A { int b; };</span>
<span id="cb14-3"><a href="#cb14-3"></a></span>
<span id="cb14-4"><a href="#cb14-4"></a>void f(A); // #1</span>
<span id="cb14-5"><a href="#cb14-5"></a>void f(B); // #2</span>
<span id="cb14-6"><a href="#cb14-6"></a></span>
<span id="cb14-7"><a href="#cb14-7"></a>void g() {</span>
<span id="cb14-8"><a href="#cb14-8"></a>    f({.a=1}); // OK (calls #1) in C++23, now ill-formed (ambiguous)</span>
<span id="cb14-9"><a href="#cb14-9"></a>}</span></code></pre></div>
</blockquote>
</div>
<h2 data-number="4.3" id="feature-test-macro"><span class="header-section-number">4.3</span> Feature-test Macro<a href="#feature-test-macro" class="self-link"></a></h2>
<p>Bump <code class="sourceCode cpp">__cpp_­designated_­initializers</code> in <span>15.11 <a href="https://wg21.link/cpp.predefined">[cpp.predefined]</a></span>:</p>
<blockquote>
<div>
<div class="sourceCode" id="cb15"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb15-1"><a href="#cb15-1"></a><span class="st">- __cpp_­designated_­initializers <span class="diffdel">201707L</span></span></span>
<span id="cb15-2"><a href="#cb15-2"></a><span class="va">+ __cpp_­designated_­initializers <span class="diffins">2023XXL</span></span></span></code></pre></div>
</div>
</blockquote>
<h1 data-number="5" style="border-bottom:1px solid #cccccc" id="acknowledgements"><span class="header-section-number">5</span> Acknowledgements<a href="#acknowledgements" class="self-link"></a></h1>
<p>Thanks to Matthias Stearn for, basically, the proposal. Thanks to Tim Song for helping with design questions and wording.</p>
<h1 data-number="6" style="border-bottom:1px solid #cccccc" id="bibliography"><span class="header-section-number">6</span> References<a href="#bibliography" class="self-link"></a></h1>
<div id="refs" class="references hanging-indent" role="doc-bibliography">
<div id="ref-P0017R1">
<p>[P0017R1] Oleg Smolsky. 2015-10-24. Extension to aggregate initialization. <br />
<a href="https://wg21.link/p0017r1">https://wg21.link/p0017r1</a></p>
</div>
<div id="ref-P0329R4">
<p>[P0329R4] Tim Shen, Richard Smith. 2017-07-12. Designated Initialization Wording. <br />
<a href="https://wg21.link/p0329r4">https://wg21.link/p0329r4</a></p>
</div>
<div id="ref-P2287R0">
<p>[P2287R0] Barry Revzin. 2021-01-21. Designated-initializers for base classes. <br />
<a href="https://wg21.link/p2287r0">https://wg21.link/p2287r0</a></p>
</div>
<div id="ref-P2287R1">
<p>[P2287R1] Barry Revzin. 2021-02-15. Designated-initializers for base classes. <br />
<a href="https://wg21.link/p2287r1">https://wg21.link/p2287r1</a></p>
</div>
</div>
</div>
</div>
</body>
</html>
