<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<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="2025-06-19" />
  <title>Splicing a base class subobject</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.csl-block{margin-left: 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; }
      .sourceCode { overflow: visible; }
      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;
text-align: justify;
}
@media screen and (max-width: 30em) {
body {
margin: 1.5em;
}
}
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;
}
td > div > 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: #C9FBC9;
--diff-strongins: #acf2bd;
--diff-del: #FFC8EB;
--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.addu td pre { background-color: inherit; }
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); }
div.std blockquote { color: #000000; background-color: #F1F1F1;
border: 1px solid #D1D1D1;
padding-left: 0.5em; padding-right: 0.5em; }
div.std.ins blockquote {
color: #000000; background-color: #C8FFC8;
border: 1px solid #B3EBB3;
}
div.ins > div.example {
color: #000000; background-color: #C8FFC8;
border: 1px solid #B3EBB3;
}
div.std div.sourceCode { background-color: inherit; margin-left: 1em; }
div.rm li {
text-decoration: line-through;
color: #000000;
}
div.std blockquote del, div.rm {
text-decoration: line-through;
color: #000000;
background-color: var(--diff-del);
border: none;
}
code del { border: 1px solid #ECB3C7; }
span.orange {
background-color: #ffa500;
}
span.yellow {
background-color: #ffff00;
}</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">Splicing a base class
subobject</h1>
<table style="border:none;float:right">
  <tr>
    <td>Document #:</td>
    <td>P3293R3 <a href="https://wg21.link/P3293">[Latest]</a> <a href="https://wg21.link/P3293/status">[Status]</a></td>
  </tr>
  <tr>
    <td>Date:</td>
    <td>2025-06-19</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>
      CWG/LWG<br>
    </td>
  </tr>
  <tr>
    <td style="vertical-align:top">Reply-to:</td>
    <td>
      Peter Dimov<br>&lt;<a href="mailto:pdimov@gmail.com" class="email">pdimov@gmail.com</a>&gt;<br>
      Dan Katz<br>&lt;<a href="mailto:dkatz85@bloomberg.net" class="email">dkatz85@bloomberg.net</a>&gt;<br>
      Barry Revzin<br>&lt;<a href="mailto:barry.revzin@gmail.com" class="email">barry.revzin@gmail.com</a>&gt;<br>
      Daveed Vandevoorde<br>&lt;<a href="mailto:daveed@edg.com" class="email">daveed@edg.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" id="toc-revision-history"><span class="toc-section-number">1</span> Revision
History<span></span></a></li>
<li><a href="#introduction" id="toc-introduction"><span class="toc-section-number">2</span> Introduction<span></span></a></li>
<li><a href="#kinds-of-subobjects" id="toc-kinds-of-subobjects"><span class="toc-section-number">3</span> Kinds of Subobjects<span></span></a>
<ul>
<li><a href="#base-class-subobjects" id="toc-base-class-subobjects"><span class="toc-section-number">3.1</span> Base Class
Subobjects<span></span></a></li>
<li><a href="#array-elements" id="toc-array-elements"><span class="toc-section-number">3.2</span> Array
Elements<span></span></a></li>
</ul></li>
<li><a href="#proposal" id="toc-proposal"><span class="toc-section-number">4</span> Proposal<span></span></a>
<ul>
<li><a href="#wording" id="toc-wording"><span class="toc-section-number">4.1</span> Wording<span></span></a></li>
</ul></li>
<li><a href="#bibliography" id="toc-bibliography"><span class="toc-section-number">5</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>Since <span class="citation" data-cites="P3293R2"><a href="https://wg21.link/p3293r2" role="doc-biblioref">[P3293R2]</a></span>, rebasing on <span class="citation" data-cites="P2996R13"><a href="https://wg21.link/p2996r13" role="doc-biblioref">[P2996R13]</a></span>. Dropped the ability to have
a pointer-to-base-class subobject in the interests of time.</p>
<p>Since <span class="citation" data-cites="P3293R1"><a href="https://wg21.link/p3293r1" role="doc-biblioref">[P3293R1]</a></span>, updating wording and design
to account for <span class="title"><span class="citation" data-cites="P3547R1"><a href="https://wg21.link/p3547r1" role="doc-biblioref">[P3547R1] (Modeling Access Control With
Reflection)</a></span></span> and rebased on <span class="citation" data-cites="P2996R12"><a href="https://wg21.link/p2996r12" role="doc-biblioref">[P2996R12]</a></span>. Adding corresponding
<code class="sourceCode cpp">has_inaccessible_subobjects</code>.</p>
<p>Since <span class="citation" data-cites="P3293R0"><a href="https://wg21.link/p3293r0" role="doc-biblioref">[P3293R0]</a></span>, noted that <code class="sourceCode cpp"><span class="op">&amp;[:</span>base<span class="op">:]</span></code>
cannot work for virtual base classes. Talking about arrays. Added
wording.</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>There are many contexts in which it is useful to perform the same
operation on each subobject of an object in sequence. These include
serialization or <a href="https://www.boost.org/doc/libs/1_85_0/libs/describe/doc/html/describe.html#example_print_function">formatting</a>
or <a href="https://www.boost.org/doc/libs/1_85_0/libs/describe/doc/html/describe.html#example_hash_value">hashing</a>.</p>
<p><span class="citation" data-cites="P2996R6"><a href="https://wg21.link/p2996r6" role="doc-biblioref">[P2996R6]</a></span> seems like it gives us an
ideal solution to this problem, in the form of being able to iterate
over all the subobjects of an object and splicing accesses to them.
However, it is not quite complete:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb1"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> T, <span class="kw">class</span> F<span class="op">&gt;</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> for_each_subobject<span class="op">(</span>T <span class="kw">const</span><span class="op">&amp;</span> obj, F f<span class="op">)</span> <span class="op">{</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span> <span class="cf">for</span> <span class="op">(</span><span class="kw">constexpr</span> <span class="kw">auto</span> sub <span class="op">:</span> subobjects_of<span class="op">(^</span>T<span class="op">))</span> <span class="op">{</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>      f<span class="op">(</span>obj<span class="op">.[:</span>sub<span class="op">:])</span>; <span class="co">// this is valid syntax for non-static data members</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>                      <span class="co">// but is invalid for base classes subobjects</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
</blockquote>
</div>
<p>Instead we have to handle bases separately from the non-static data
members:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb2"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> T, <span class="kw">class</span> F<span class="op">&gt;</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> for_each_subobject<span class="op">(</span>T <span class="kw">const</span><span class="op">&amp;</span> obj, F f<span class="op">)</span> <span class="op">{</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span> <span class="cf">for</span> <span class="op">(</span><span class="kw">constexpr</span> <span class="kw">auto</span> base <span class="op">:</span> bases_of<span class="op">(^</span>T<span class="op">))</span> <span class="op">{</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>      f<span class="op">(</span><span class="kw">static_cast</span><span class="op">&lt;</span>type_of<span class="op">(</span>base<span class="op">)</span> <span class="kw">const</span><span class="op">&amp;&gt;(</span>obj<span class="op">))</span>;</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span> <span class="cf">for</span> <span class="op">(</span><span class="kw">constexpr</span> <span class="kw">auto</span> sub <span class="op">:</span> nonstatic_data_members_of<span class="op">(^</span>T<span class="op">))</span> <span class="op">{</span></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a>      f<span class="op">(</span>obj<span class="op">.[:</span>sub<span class="op">:])</span>;</span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
</blockquote>
</div>
<p>Except this is now a normal
<code class="sourceCode cpp"><span class="kw">static_cast</span></code>
and so requires access checking, thus prohibiting accessing private base
classes.</p>
<p>We could avoid access checking by using a C-style cast:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb3"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> T, <span class="kw">class</span> F<span class="op">&gt;</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> for_each_subobject<span class="op">(</span>T <span class="kw">const</span><span class="op">&amp;</span> obj, F f<span class="op">)</span> <span class="op">{</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span> <span class="cf">for</span> <span class="op">(</span><span class="kw">constexpr</span> <span class="kw">auto</span> base <span class="op">:</span> bases_of<span class="op">(^</span>T<span class="op">))</span> <span class="op">{</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>      f<span class="op">((</span><span class="kw">typename</span> <span class="op">[:</span> type_of<span class="op">(</span>base<span class="op">)</span> <span class="op">:]&amp;)</span>obj<span class="op">)</span>;</span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span> <span class="cf">for</span> <span class="op">(</span><span class="kw">constexpr</span> <span class="kw">auto</span> sub <span class="op">:</span> nonstatic_data_members_of<span class="op">(^</span>T<span class="op">))</span> <span class="op">{</span></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>      f<span class="op">(</span>obj<span class="op">.[:</span>sub<span class="op">:])</span>;</span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
</blockquote>
</div>
<p>But this opens up other problems: I forgot to write
<code class="sourceCode cpp"><span class="kw">const</span></code> and so
now I accidentally cast away
<code class="sourceCode cpp"><span class="kw">const</span></code>-ness
unintentionally. Oops. Not to mention that this cast actually works
regardless of whether <code class="sourceCode cpp">base</code> refers to
a base class of <code class="sourceCode cpp">T</code>, so it’s not
exactly the best programming practice.</p>
<p>On top of that, both the
<code class="sourceCode cpp"><span class="kw">static_cast</span></code>
and C-style cast approaches suffer from having to correctly spell the
destination type - which requires manually propagating the const-ness
and value category of the object.</p>
<p>The way to avoid all of these problems is to just defer to a function
template:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb4"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span>std<span class="op">::</span>meta<span class="op">::</span>info M, <span class="kw">class</span> T<span class="op">&gt;</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="kw">auto</span> subobject_cast<span class="op">(</span>T<span class="op">&amp;&amp;</span> arg<span class="op">)</span> <span class="op">-&gt;</span> <span class="kw">auto</span><span class="op">&amp;&amp;</span> <span class="op">{</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> <span class="kw">auto</span> stripped <span class="op">=</span> remove_cvref<span class="op">(^</span>T<span class="op">)</span>;</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="kw">constexpr</span> <span class="op">(</span>is_base<span class="op">(</span>M<span class="op">))</span> <span class="op">{</span></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>        <span class="kw">static_assert</span><span class="op">(</span>is_base_of<span class="op">(</span>type_of<span class="op">(</span>M<span class="op">)</span>, stripped<span class="op">))</span>;</span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="op">(</span><span class="kw">typename</span> <span class="op">[:</span> copy_cvref<span class="op">(^</span>T, type_of<span class="op">(</span>M<span class="op">))</span> <span class="op">:]&amp;)</span>arg;</span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a>        <span class="kw">static_assert</span><span class="op">(</span>parent_of<span class="op">(</span>M<span class="op">)</span> <span class="op">==</span> stripped<span class="op">)</span>;</span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="op">((</span>T<span class="op">&amp;&amp;)</span>arg<span class="op">).[:</span>M<span class="op">:]</span>;</span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb4-12"><a href="#cb4-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-13"><a href="#cb4-13" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> T, <span class="kw">class</span> F<span class="op">&gt;</span></span>
<span id="cb4-14"><a href="#cb4-14" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> for_each_subobject<span class="op">(</span>T <span class="kw">const</span><span class="op">&amp;</span> obj, F f<span class="op">)</span> <span class="op">{</span></span>
<span id="cb4-15"><a href="#cb4-15" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span> <span class="cf">for</span> <span class="op">(</span><span class="kw">constexpr</span> <span class="kw">auto</span> sub <span class="op">:</span> subobjects_of<span class="op">(^</span>T<span class="op">))</span> <span class="op">{</span></span>
<span id="cb4-16"><a href="#cb4-16" aria-hidden="true" tabindex="-1"></a>      f<span class="op">(</span>subobject_cast<span class="op">&lt;</span>sub<span class="op">&gt;(</span>obj<span class="op">))</span>;</span>
<span id="cb4-17"><a href="#cb4-17" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb4-18"><a href="#cb4-18" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
</blockquote>
</div>
<p>But this feels a bit silly? Why should we have to write this?</p>
<h1 data-number="3" style="border-bottom:1px solid #cccccc" id="kinds-of-subobjects"><span class="header-section-number">3</span>
Kinds of Subobjects<a href="#kinds-of-subobjects" class="self-link"></a></h1>
<p>There are three kinds of subobjects as specified in <span>6.7.2 <a href="https://wg21.link/intro.object">[intro.object]</a></span>:</p>
<div class="std">
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_1" id="pnum_1">2</a></span>
Objects can contain other objects, called <em>subobjects</em>. A
subobject can be a <em>member subobject</em> ([class.mem]), a <em>base
class subobject</em> ([class.derived]), or an array element.</p>
</blockquote>
</div>
<p>Currently, the reflection proposal only supports splicing member
subobjects. Let’s go over the other two.</p>
<h2 data-number="3.1" id="base-class-subobjects"><span class="header-section-number">3.1</span> Base Class Subobjects<a href="#base-class-subobjects" class="self-link"></a></h2>
<p>Unlike member subobjects, there is <em>no</em> way today to access a
base class subobject directly outside of one of the casts described
above. Part of the reason for this is that while a data member is always
just an <code class="sourceCode cpp"><em>identifier</em></code>, a base
class subobject can have an arbitrary complex name. Reflection allows us
to sidestep the question of complex names since we just have a
reflection to the appropriate base class subobject already, so it
becomes a matter of asking what <code class="sourceCode cpp">obj<span class="op">.[:</span>base<span class="op">:]</span></code>
means.</p>
<p>But what else could it mean? We argue that the obvious, useful, and
only possible meaning of this syntax would be to access the appropriate
base class subobject (in the same way that <code class="sourceCode cpp">obj<span class="op">.[:</span>nsdm<span class="op">:]</span></code>
— where <code class="sourceCode cpp">nsdm</code> represents a non-static
data member — is access to that data member).</p>
<p>Additionally, <code class="sourceCode cpp"><span class="op">&amp;[:</span>base<span class="op">:]</span></code>
where <code class="sourceCode cpp">base</code> represents a base class
<code class="sourceCode cpp">B</code> of type
<code class="sourceCode cpp">T</code> could yield a
<code class="sourceCode cpp">B T<span class="op">::*</span></code> with
appropriate offset. Likewise, there is no way to directly get such a
member pointer today. But that would be a useful bit of functionality to
add. That is, unless <code class="sourceCode cpp">base</code> represents
a reflection of a virtual base class subobject, which wouldn’t be
representable as a pointer to member. However, in the interests of time,
we removed that functionality on the way to merging this paper in
Sofia.</p>
<p>The only reason <span class="citation" data-cites="P2996R6"><a href="https://wg21.link/p2996r6" role="doc-biblioref">[P2996R6]</a></span> doesn’t support splicing base
class subobjects is the lack of equivalent language support today. This
means that adding this support in reflection would mean that splicing
can achieve something the language cannot do natively. But we don’t
really see that as a problem. Reflection is already allowing all sorts
of things that the language cannot do natively. What’s one more?</p>
<h2 data-number="3.2" id="array-elements"><span class="header-section-number">3.2</span> Array Elements<a href="#array-elements" class="self-link"></a></h2>
<p>The more complicated question is array elements. <code class="sourceCode cpp">subobjects_of<span class="op">(^</span><span class="dt">int</span><span class="op">[</span><span class="dv">4</span><span class="op">])</span></code>
needs to return four subobjects, which would effectively each represent
“index <code class="sourceCode cpp">i</code> into <code class="sourceCode cpp"><span class="dt">int</span><span class="op">[</span><span class="dv">4</span><span class="op">]</span></code>”
for each <code class="sourceCode cpp">i</code> in <code class="sourceCode cpp"><span class="op">[</span><span class="dv">0</span>, <span class="dv">1</span>, <span class="dv">2</span>, <span class="dv">3</span><span class="op">]</span></code>.
We would want both the index and the type here. That, in of itself,
isn’t any different from dealing with the non-static data members of a
class. These subobjects likewise have offsets, types, etc, in the same
way.</p>
<p>The challenge is more in terms of access. With base class subobjects,
we talked about how there is no non-splice equivalent to <code class="sourceCode cpp">obj<span class="op">.[:</span>base<span class="op">:]</span></code>.
But today there isn’t any even any such valid syntax for arrays today at
all! Indeed, the standard refers to the expression
<code class="sourceCode cpp">E1<span class="op">.</span>E2</code> as
<em>class</em> member access (<span>7.6.1.5 <a href="https://wg21.link/expr.ref">[expr.ref]</a></span>), and arrays are
not actually classes. That adds complexity.</p>
<p>Moreover, arrays have the additional problem that the number of array
elements can explode quite quickly. <code class="sourceCode cpp"><span class="dt">int</span><span class="op">[</span><span class="dv">1&#39;000</span><span class="op">]</span></code>
already has 1000 subobjects. That’s expensive. Especially since array
elements aren’t quite the same as the other kinds of subobjects — we
know they are all the same type. All the use-cases that we have, unlike
for base class subobjects, would want to treat arrays separately
anyway.</p>
<p>That is, being able to splice base class subobjects is small language
extension with good bang for the buck. Being able to splice array
subobjects requires being able to even represent array subobjects as
reflections (which currently does not exist) as well as being able to
extend class member access to support arrays. Not to mention pointers to
members? It’s a much larger change with a much smaller benefit.</p>
<h1 data-number="4" style="border-bottom:1px solid #cccccc" id="proposal"><span class="header-section-number">4</span> Proposal<a href="#proposal" class="self-link"></a></h1>
<p>We propose to define <code class="sourceCode cpp">obj<span class="op">.[:</span>base<span class="op">:]</span></code>
(where <code class="sourceCode cpp">base</code> is a reflection of a
base class of the type of <code class="sourceCode cpp">obj</code>) as
being an access to that base class subobject, in the same way that <code class="sourceCode cpp">obj<span class="op">.[:</span>nsdm<span class="op">:]</span></code>
(where <code class="sourceCode cpp">nsdm</code> is a reflection of a
non-static data member) is an access to that data member.</p>
<p>We argue that this is the obvious, useful, and only possible meaning
of this syntax, so we should simply support them in the language.</p>
<p>The only reason this isn’t initially part of <span class="citation" data-cites="P2996R6"><a href="https://wg21.link/p2996r6" role="doc-biblioref">[P2996R6]</a></span> is that while there
<em>is</em> a way to access a data member of an object directly (just
<code class="sourceCode cpp">obj<span class="op">.</span>mem</code>),
there is <em>no</em> way to access a base class subobject directly
outside of one of the casts described above.</p>
<p>We then additionally propose to back <code class="sourceCode cpp">subobjects_of<span class="op">()</span></code>
that <span class="citation" data-cites="P2996R6"><a href="https://wg21.link/p2996r6" role="doc-biblioref">[P2996R6]</a></span> removed. This was removed
because iterating over <em>all</em> the subobjects uniformly wasn’t
really possible until these language additions.</p>
<h2 data-number="4.1" id="wording"><span class="header-section-number">4.1</span> Wording<a href="#wording" class="self-link"></a></h2>
<p>The wording here is a diff on top of P2996.</p>
<p>Adjust the
<code class="sourceCode cpp"><em>splice-expression</em></code>
restriction added by P2996 and handle base class splices in
<span>7.6.1.5 <a href="https://wg21.link/expr.ref">[expr.ref]</a></span>/7-8:</p>
<div class="std">
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_2" id="pnum_2">*</a></span>
If <code class="sourceCode cpp">E2</code> is a
<code class="sourceCode cpp"><em>splice-expression</em></code>, then
<span class="addu">let <code class="sourceCode cpp">T1</code> be the
type of <code class="sourceCode cpp">E1</code>.</span>
<code class="sourceCode cpp">E2</code> shall designate <span class="addu">either</span> a member of <span class="rm" style="color: #bf0303"><del>the type of
<span><code class="sourceCode default">E1</code></span></del></span>
<span class="addu"><code class="sourceCode cpp">T1</code> or a direct
base class relationship (<code class="sourceCode cpp">T1</code>,
<code class="sourceCode cpp">B</code>)</span>.</p>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_3" id="pnum_3">6</a></span>
If <code class="sourceCode cpp">E2</code> designates a bit-field,
<code class="sourceCode cpp">E1<span class="op">.</span>E2</code> is a
bit-field. […]</p>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_4" id="pnum_4">7</a></span>
If <code class="sourceCode cpp">E2</code> designates an entity that is
declared to have type “reference to
<code class="sourceCode cpp">T</code>”, then
<code class="sourceCode cpp">E1<span class="op">.</span>E2</code> is an
lvalue of type <code class="sourceCode cpp">T</code>. In that case, if
<code class="sourceCode cpp">E2</code> designates a static data member,
<code class="sourceCode cpp">E1<span class="op">.</span>E2</code>
designates the object or function to which the reference is bound,
otherwise
<code class="sourceCode cpp">E1<span class="op">.</span>E2</code>
designates the object or function to which the corresponding reference
member of <code class="sourceCode cpp">E1</code> is bound. Otherwise,
one of the following rules applies.</p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_5" id="pnum_5">(7.1)</a></span>
If <code class="sourceCode cpp">E2</code> designates a static data
member and the type of <code class="sourceCode cpp">E2</code> is
<code class="sourceCode cpp">T</code>, then
<code class="sourceCode cpp">E1<span class="op">.</span>E2</code> is an
lvalue; […]</li>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_6" id="pnum_6">(7.2)</a></span>
Otherwise, if <code class="sourceCode cpp">E2</code> designates a
non-static data member and the type of
<code class="sourceCode cpp">E1</code> is “<em>cq1</em> <em>vq1</em>
<code class="sourceCode cpp">X</code>”, and the type of
<code class="sourceCode cpp">E2</code> is “<em>cq2 vq2</em>
<code class="sourceCode cpp">T</code>”, the expression designates the
corresponding member subobject of the object designated by <span class="rm" style="color: #bf0303"><del>the first expression</del></span>
<span class="addu"><code class="sourceCode cpp">E1</code></span>.
[…]</li>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_7" id="pnum_7">(7.3)</a></span>
Otherwise, if <code class="sourceCode cpp">E2</code> is an overload set,
[…]</li>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_8" id="pnum_8">(7.4)</a></span>
Otherwise, if <code class="sourceCode cpp">E2</code> designates a nested
type, the expression
<code class="sourceCode cpp">E1<span class="op">.</span>E2</code> is
ill-formed.</li>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_9" id="pnum_9">(7.5)</a></span>
Otherwise, if <code class="sourceCode cpp">E2</code> designates a member
enumerator […]</li>
</ul>
<div class="addu">
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized" href="#pnum_10" id="pnum_10">(7.6)</a></span>
Otherwise, if <code class="sourceCode cpp">E2</code> designates a direct
base class relationship (<code class="sourceCode cpp"><em>D</em></code>,
<code class="sourceCode cpp"><em>B</em></code>) and the type of
<code class="sourceCode cpp">E1</code> is
<code class="sourceCode cpp"><em>cv</em> T</code>, the expression
designates the direct base class subobject of type
<code class="sourceCode cpp"><em>B</em></code> of the object designated
by <code class="sourceCode cpp">E1</code>. If
<code class="sourceCode cpp">E1</code> is an lvalue, then
<code class="sourceCode cpp">E1<span class="op">.</span>E2</code> is an
lvalue; otherwise,
<code class="sourceCode cpp">E1<span class="op">.</span>E2</code> is an
xvalue. The type of
<code class="sourceCode cpp">E1<span class="op">.</span>E2</code> is
“<code class="sourceCode cpp"><em>cv</em> <em>B</em></code>”. <span class="note"><span>[ <em>Note 1:</em> </span>This can only occur in an
expression of the form <code class="sourceCode cpp">e1<span class="op">.[:</span>e2<span class="op">:]</span></code>.<span>
— <em>end note</em> ]</span></span></p>
<div class="example">
<span>[ <em>Example 1:</em> </span>
<div class="sourceCode" id="cb5"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> B <span class="op">{</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> b;</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> C <span class="op">:</span> B <span class="op">{</span></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> get<span class="op">()</span> <span class="kw">const</span> <span class="op">{</span> <span class="cf">return</span> b; <span class="op">}</span></span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> D <span class="op">:</span> B, C <span class="op">{</span> <span class="op">}</span>;</span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="dt">int</span> f<span class="op">()</span> <span class="op">{</span></span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a>  D d <span class="op">=</span> <span class="op">{</span><span class="dv">1</span>, <span class="op">{}}</span>;</span>
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-12"><a href="#cb5-12" aria-hidden="true" tabindex="-1"></a>  <span class="co">// b unambiguously refers to the direct base class of type B,</span></span>
<span id="cb5-13"><a href="#cb5-13" aria-hidden="true" tabindex="-1"></a>  <span class="co">// not the indirect base class of type B</span></span>
<span id="cb5-14"><a href="#cb5-14" aria-hidden="true" tabindex="-1"></a>  B<span class="op">&amp;</span> b <span class="op">=</span> d<span class="op">.[:</span> std<span class="op">::</span>meta<span class="op">::</span>bases_of<span class="op">(^^</span>D, std<span class="op">::</span>meta<span class="op">::</span>access_context<span class="op">::</span>current<span class="op">())[</span><span class="dv">0</span><span class="op">]</span> <span class="op">:]</span>;</span>
<span id="cb5-15"><a href="#cb5-15" aria-hidden="true" tabindex="-1"></a>  b<span class="op">.</span>b <span class="op">+=</span> <span class="dv">10</span>;</span>
<span id="cb5-16"><a href="#cb5-16" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> <span class="dv">10</span> <span class="op">*</span> b<span class="op">.</span>b <span class="op">+</span> d<span class="op">.</span>get<span class="op">()</span>;</span>
<span id="cb5-17"><a href="#cb5-17" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb5-18"><a href="#cb5-18" aria-hidden="true" tabindex="-1"></a><span class="kw">static_assert</span><span class="op">(</span>f<span class="op">()</span> <span class="op">==</span> <span class="dv">110</span><span class="op">)</span>;</span></code></pre></div>
<span> — <em>end example</em> ]</span>
</div></li>
</ul>
</div>
<ul>
<li><span class="marginalizedparent"><a class="marginalized" href="#pnum_11" id="pnum_11">(7.7)</a></span>
Otherwise, the program is ill-formed.</li>
</ul>
</blockquote>
</div>
<p>Add to meta.synop:</p>
<div class="std">
<blockquote>
<div>
<div class="sourceCode" id="cb6"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a>namespace std::meta {</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>  // ...</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>  // [meta.reflection.access.queries], member accessibility queries</span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>  consteval bool is_accessible(info r, access_context ctx);</span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>  consteval bool has_inaccessible_nonstatic_data_members(</span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>      info r,</span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a>      access_context ctx);</span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a>  consteval bool has_inaccessible_bases(info r, access_context ctx);</span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true" tabindex="-1"></a><span class="va">+ consteval bool has_inaccessible_subobjects(info r, access_context ctx);</span></span>
<span id="cb6-11"><a href="#cb6-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-12"><a href="#cb6-12" aria-hidden="true" tabindex="-1"></a>  // [meta.reflection.member.queries], reflection member queries</span>
<span id="cb6-13"><a href="#cb6-13" aria-hidden="true" tabindex="-1"></a>  consteval vector&lt;info&gt; members_of(info r, access_context ctx);</span>
<span id="cb6-14"><a href="#cb6-14" aria-hidden="true" tabindex="-1"></a>  consteval vector&lt;info&gt; bases_of(info type, access_context ctx);</span>
<span id="cb6-15"><a href="#cb6-15" aria-hidden="true" tabindex="-1"></a>  consteval vector&lt;info&gt; static_data_members_of(info type, access_context ctx);</span>
<span id="cb6-16"><a href="#cb6-16" aria-hidden="true" tabindex="-1"></a>  consteval vector&lt;info&gt; nonstatic_data_members_of(info type, access_context ctx);</span>
<span id="cb6-17"><a href="#cb6-17" aria-hidden="true" tabindex="-1"></a><span class="va">+ consteval vector&lt;info&gt; subobjects_of(info type, access_context ctx);</span></span>
<span id="cb6-18"><a href="#cb6-18" aria-hidden="true" tabindex="-1"></a>  consteval vector&lt;info&gt; enumerators_of(info type_enum);</span>
<span id="cb6-19"><a href="#cb6-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-20"><a href="#cb6-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-21"><a href="#cb6-21" aria-hidden="true" tabindex="-1"></a>  // ...</span>
<span id="cb6-22"><a href="#cb6-22" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
</div>
</blockquote>
</div>
<p>Add to [meta.reflection.access.queries] in the appropriate spot:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb7"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> <span class="dt">bool</span> has_inaccessible_bases<span class="op">(</span>info r, access_context ctx<span class="op">)</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_12" id="pnum_12">7</a></span>
<em>Constant When</em>: <code class="sourceCode cpp">bases_of<span class="op">(</span>r, ctx<span class="op">)</span></code>
is a constant subexpression.</p>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_13" id="pnum_13">8</a></span>
<em>Returns</em>:
<code class="sourceCode cpp"><span class="kw">true</span></code> if
<code class="sourceCode cpp">is_accessible<span class="op">(</span><em>R</em>, ctx<span class="op">)</span></code>
is <code class="sourceCode cpp"><span class="kw">false</span></code> for
any <code class="sourceCode cpp"><em>R</em></code> in <code class="sourceCode cpp">bases_of<span class="op">(</span>r, access_context<span class="op">::</span>unchecked<span class="op">())</span></code>.
Otherwise,
<code class="sourceCode cpp"><span class="kw">false</span></code>.</p>
<div class="addu">
<div class="sourceCode" id="cb8"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> <span class="dt">bool</span> has_inaccessible_subobjects<span class="op">(</span>info r, access_context ctx<span class="op">)</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_14" id="pnum_14">9</a></span>
<em>Effects</em>: Equivalent to: <code class="sourceCode cpp"><span class="cf">return</span> has_inaccessible_bases<span class="op">(</span>r, ctx<span class="op">)</span> <span class="op">||</span> has_inaccessible_nonstatic_data_members<span class="op">(</span>r, ctx<span class="op">)</span>;</code></p>
</div>
</blockquote>
</div>
<p>Add to [meta.reflection.member.queries] in the appropriate spot:</p>
<div class="std">
<blockquote>
<div class="sourceCode" id="cb9"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> vector<span class="op">&lt;</span>info<span class="op">&gt;</span> nonstatic_data_members_of<span class="op">(</span>info type, access_context ctx<span class="op">)</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_15" id="pnum_15">9</a></span>
<em>Constant When</em>: <code class="sourceCode cpp">dealias<span class="op">(</span>type<span class="op">)</span></code>
represents a class type that is complete from some point in the
evaluation context.</p>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_16" id="pnum_16">10</a></span>
<em>Returns</em>: A <code class="sourceCode cpp">vector</code>
containing each element <code class="sourceCode cpp">e</code> of <code class="sourceCode cpp">members_of<span class="op">(</span>type, ctx<span class="op">)</span></code>
such that <code class="sourceCode cpp">is_nonstatic_data_member<span class="op">(</span>e<span class="op">)</span></code>
is <code class="sourceCode cpp"><span class="kw">true</span></code>,
preserving their order.</p>
<div class="addu">
<div class="sourceCode" id="cb10"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a>consteval vector&lt;info&gt; subobjects_of(info type, access_context ctx);</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_17" id="pnum_17">10+1</a></span>
<em>Constant When</em>: <code class="sourceCode cpp">dealias<span class="op">(</span>type<span class="op">)</span></code>
represents a class type that is complete from some point in the
evaluation context.</p>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_18" id="pnum_18">10+2</a></span>
<em>Returns</em>: A <code class="sourceCode cpp">vector</code>
containing each element of <code class="sourceCode cpp">bases_of<span class="op">(</span>type, ctx<span class="op">)</span></code>
followed by each element of <code class="sourceCode cpp">nonstatic_data_members_of<span class="op">(</span>type, ctx<span class="op">)</span></code>,
preserving their order.</p>
</div>
<div class="sourceCode" id="cb11"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="kw">consteval</span> vector<span class="op">&lt;</span>info<span class="op">&gt;</span> enumerators_of<span class="op">(</span>info type_enum<span class="op">)</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_19" id="pnum_19">11</a></span>
<em>Constant When</em>: <code class="sourceCode cpp">dealias<span class="op">(</span>type_enum<span class="op">)</span></code>
represents an enumeration type and <code class="sourceCode cpp">is_enumerable_type<span class="op">(</span>type_enum<span class="op">)</span></code>
is <code class="sourceCode cpp"><span class="kw">true</span></code>.</p>
<p><span class="marginalizedparent"><a class="marginalized" href="#pnum_20" id="pnum_20">12</a></span>
<em>Returns</em>: A <code class="sourceCode cpp">vector</code>
containing the reflections of each enumerator of the enumeration
represented by <code class="sourceCode cpp">dealias<span class="op">(</span>type_enum<span class="op">)</span></code>,
in the order in which they are declared.</p>
</blockquote>
</div>
<h1 data-number="5" style="border-bottom:1px solid #cccccc" id="bibliography"><span class="header-section-number">5</span>
References<a href="#bibliography" class="self-link"></a></h1>
<div id="refs" class="references csl-bib-body hanging-indent" data-entry-spacing="1" role="doc-bibliography">
<div id="ref-P2996R12" class="csl-entry" role="doc-biblioentry">
[P2996R12] Barry Revzin, Wyatt Childers, Peter Dimov, Andrew Sutton,
Faisal Vali, Daveed Vandevoorde, and Dan Katz. 2025-05-11. Reflection
for C++26. <a href="https://wg21.link/p2996r12"><div class="csl-block">https://wg21.link/p2996r12</div></a>
</div>
<div id="ref-P2996R13" class="csl-entry" role="doc-biblioentry">
[P2996R13] Barry Revzin, Wyatt Childers, Peter Dimov, Andrew Sutton,
Faisal Vali, Daveed Vandevoorde, and Dan Katz. 2025-06-18. Reflection
for C++26. <a href="https://wg21.link/p2996r13"><div class="csl-block">https://wg21.link/p2996r13</div></a>
</div>
<div id="ref-P2996R6" class="csl-entry" role="doc-biblioentry">
[P2996R6] Barry Revzin, Wyatt Childers, Peter Dimov, Andrew Sutton,
Faisal Vali, Daveed Vandevoorde, Dan Katz. 2024-10-10. Reflection for
C++26. <a href="https://wg21.link/p2996r6"><div class="csl-block">https://wg21.link/p2996r6</div></a>
</div>
<div id="ref-P3293R0" class="csl-entry" role="doc-biblioentry">
[P3293R0] Barry Revzin, Peter Dimov, Dan Katz, Daveed Vandevoorde.
2024-05-20. Splicing a base class subobject. <a href="https://wg21.link/p3293r0"><div class="csl-block">https://wg21.link/p3293r0</div></a>
</div>
<div id="ref-P3293R1" class="csl-entry" role="doc-biblioentry">
[P3293R1] Barry Revzin, Peter Dimov, Dan Katz, Daveed Vandevoorde.
2024-10-13. Splicing a base class subobject. <a href="https://wg21.link/p3293r1"><div class="csl-block">https://wg21.link/p3293r1</div></a>
</div>
<div id="ref-P3293R2" class="csl-entry" role="doc-biblioentry">
[P3293R2] Barry Revzin, Peter Dimov, Dan Katz, Daveed Vandevoorde.
2025-05-11. Splicing a base class subobject. <a href="https://wg21.link/p3293r2"><div class="csl-block">https://wg21.link/p3293r2</div></a>
</div>
<div id="ref-P3547R1" class="csl-entry" role="doc-biblioentry">
[P3547R1] Dan Katz, Ville Voutilainen. 2025-02-09. Modeling Access
Control With Reflection. <a href="https://wg21.link/p3547r1"><div class="csl-block">https://wg21.link/p3547r1</div></a>
</div>
</div>
</div>
</div>
</body>
</html>
