<!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-12-16" />
  <title>Forwarding reference to specific type/template</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">Forwarding reference to specific type/template</h1>

<table style="border:none;float:right">
  <tr>
    <td>Document #:</td>
    <td>P2481R2</td>
  </tr>
  <tr>
    <td>Date:</td>
    <td>2023-12-16</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>
<ul>
<li><a href="#stdtuple-converting-constructor"><span class="toc-section-number">2.1</span> <code class="sourceCode cpp">std<span class="op">::</span>tuple</code> converting constructor<span></span></a></li>
<li><a href="#stdget-for-stdtuple"><span class="toc-section-number">2.2</span> <code class="sourceCode cpp">std<span class="op">::</span>get</code> for <code class="sourceCode cpp">std<span class="op">::</span>tuple</code><span></span></a></li>
<li><a href="#transform-for-stdoptional"><span class="toc-section-number">2.3</span> <code class="sourceCode cpp">transform</code> for <code class="sourceCode cpp">std<span class="op">::</span>optional</code><span></span></a></li>
<li><a href="#view_interface-members"><span class="toc-section-number">2.4</span> <code class="sourceCode cpp">view_interface</code> members<span></span></a></li>
<li><a href="#the-goal"><span class="toc-section-number">2.5</span> The Goal<span></span></a></li>
</ul></li>
<li><a href="#the-ideas"><span class="toc-section-number">3</span> The Ideas<span></span></a>
<ul>
<li><a href="#t-auto"><span class="toc-section-number">3.1</span> <code class="sourceCode cpp">T <span class="kw">auto</span><span class="op">&amp;&amp;</span></code><span></span></a></li>
<li><a href="#t"><span class="toc-section-number">3.2</span> <code class="sourceCode cpp">T<span class="op">&amp;&amp;&amp;</span></code><span></span></a></li>
<li><a href="#forward-t"><span class="toc-section-number">3.3</span> <code class="sourceCode cpp">forward T</code><span></span></a></li>
<li><a href="#non-forward-reference-syntaxes"><span class="toc-section-number">3.4</span> Non-forward reference syntaxes<span></span></a></li>
</ul></li>
<li><a href="#proposal"><span class="toc-section-number">4</span> Proposal<span></span></a></li>
<li><a href="#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>When <span class="citation" data-cites="P2481R1">[<a href="#ref-P2481R1" role="doc-biblioref">P2481R1</a>]</span> was discussed in Issaquah, three polls were taken. There was weak consensus to solve the problem as a whole, but there was clear preference to see “a new forwarding reference syntax”:</p>
<table>
<thead>
<tr class="header">
<th><div style="text-align:center">
<strong>SF</strong>
</div></th>
<th><div style="text-align:center">
<strong>F</strong>
</div></th>
<th><div style="text-align:center">
<strong>N</strong>
</div></th>
<th><div style="text-align:center">
<strong>A</strong>
</div></th>
<th><div style="text-align:center">
<strong>SA</strong>
</div></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>1</td>
<td>7</td>
<td>3</td>
<td>0</td>
<td>0</td>
</tr>
</tbody>
</table>
<p>Over “additional syntax in the parameter declaration”:</p>
<table>
<thead>
<tr class="header">
<th><div style="text-align:center">
<strong>SF</strong>
</div></th>
<th><div style="text-align:center">
<strong>F</strong>
</div></th>
<th><div style="text-align:center">
<strong>N</strong>
</div></th>
<th><div style="text-align:center">
<strong>A</strong>
</div></th>
<th><div style="text-align:center">
<strong>SA</strong>
</div></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>3</td>
<td>2</td>
<td>4</td>
<td>1</td>
<td>2</td>
</tr>
</tbody>
</table>
<p>So this paper focuses on trying to find a solution that satisfies that preference.</p>
<p>Since <span class="citation" data-cites="P2481R0">[<a href="#ref-P2481R0" role="doc-biblioref">P2481R0</a>]</span>, added <a href="#circles-approach">Circle’s approach</a> and a choice implementor quote.</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 situations where the goal of a function template is deduce an arbitrary type - an arbitrary range, an arbitrary value, an arbitrary predicate, and so forth. But sometimes, we need something more specific. While we still want to allow for deducing <code class="sourceCode cpp"><span class="kw">const</span></code> vs mutable and lvalue vs rvalue, we know either what concrete type or concrete class template we need - and simply want to deduce <em>just</em> that. With the adoption of <span class="citation" data-cites="P0847R7">[<a href="#ref-P0847R7" role="doc-biblioref">P0847R7</a>]</span>, the incidence of this will only go up.</p>
<p>It may help if I provide a few examples.</p>
<h2 data-number="2.1" id="stdtuple-converting-constructor"><span class="header-section-number">2.1</span> <code class="sourceCode cpp">std<span class="op">::</span>tuple</code> converting constructor<a href="#stdtuple-converting-constructor" class="self-link"></a></h2>
<p><code class="sourceCode cpp">std<span class="op">::</span>tuple<span class="op">&lt;</span>T<span class="op">...&gt;</span></code> is constructible from <code class="sourceCode cpp">std<span class="op">::</span>tuple<span class="op">&lt;</span>U<span class="op">...&gt;</span> <em>cv</em> <em>ref</em></code> when <code class="sourceCode cpp">T<span class="op">...</span></code> and <code class="sourceCode cpp">U<span class="op">...</span></code> are the same size and each <code class="sourceCode cpp">T</code> is constructible from <code class="sourceCode cpp">U <em>cv</em> <em>ref</em></code> (plus another constraint to avoid clashing with other constructors that I’m just going to ignore for the purposes of this paper). The way this would be written today is:</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">template</span> <span class="op">&lt;</span><span class="kw">typename</span><span class="op">...</span> Ts<span class="op">&gt;</span></span>
<span id="cb1-2"><a href="#cb1-2"></a><span class="kw">struct</span> tuple <span class="op">{</span></span>
<span id="cb1-3"><a href="#cb1-3"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span><span class="op">...</span> Us<span class="op">&gt;</span></span>
<span id="cb1-4"><a href="#cb1-4"></a>        <span class="kw">requires</span> <span class="kw">sizeof</span><span class="op">...(</span>Ts<span class="op">)</span> <span class="op">==</span> <span class="kw">sizeof</span><span class="op">...(</span>Us<span class="op">)</span></span>
<span id="cb1-5"><a href="#cb1-5"></a>              <span class="op">&amp;&amp;</span> <span class="op">(</span>is_constructible_v<span class="op">&lt;</span>Ts, Us<span class="op">&amp;&gt;</span> <span class="op">&amp;&amp;</span> <span class="op">...)</span></span>
<span id="cb1-6"><a href="#cb1-6"></a>    tuple<span class="op">(</span>tuple<span class="op">&lt;</span>Us<span class="op">...&gt;&amp;)</span>;</span>
<span id="cb1-7"><a href="#cb1-7"></a></span>
<span id="cb1-8"><a href="#cb1-8"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span><span class="op">...</span> Us<span class="op">&gt;</span></span>
<span id="cb1-9"><a href="#cb1-9"></a>        <span class="kw">requires</span> <span class="kw">sizeof</span><span class="op">...(</span>Ts<span class="op">)</span> <span class="op">==</span> <span class="kw">sizeof</span><span class="op">...(</span>Us<span class="op">)</span></span>
<span id="cb1-10"><a href="#cb1-10"></a>              <span class="op">&amp;&amp;</span> <span class="op">(</span>is_constructible_v<span class="op">&lt;</span>Ts, Us <span class="kw">const</span><span class="op">&amp;&gt;</span> <span class="op">&amp;&amp;</span> <span class="op">...)</span></span>
<span id="cb1-11"><a href="#cb1-11"></a>    tuple<span class="op">(</span>tuple<span class="op">&lt;</span>Us<span class="op">...&gt;</span> <span class="kw">const</span><span class="op">&amp;)</span>;</span>
<span id="cb1-12"><a href="#cb1-12"></a></span>
<span id="cb1-13"><a href="#cb1-13"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span><span class="op">...</span> Us<span class="op">&gt;</span></span>
<span id="cb1-14"><a href="#cb1-14"></a>        <span class="kw">requires</span> <span class="kw">sizeof</span><span class="op">...(</span>Ts<span class="op">)</span> <span class="op">==</span> <span class="kw">sizeof</span><span class="op">...(</span>Us<span class="op">)</span></span>
<span id="cb1-15"><a href="#cb1-15"></a>              <span class="op">&amp;&amp;</span> <span class="op">(</span>is_constructible_v<span class="op">&lt;</span>Ts, Us<span class="op">&amp;&amp;&gt;</span> <span class="op">&amp;&amp;</span> <span class="op">...)</span></span>
<span id="cb1-16"><a href="#cb1-16"></a>    tuple<span class="op">(</span>tuple<span class="op">&lt;</span>Us<span class="op">...&gt;&amp;&amp;)</span>;</span>
<span id="cb1-17"><a href="#cb1-17"></a></span>
<span id="cb1-18"><a href="#cb1-18"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span><span class="op">...</span> Us<span class="op">&gt;</span></span>
<span id="cb1-19"><a href="#cb1-19"></a>        <span class="kw">requires</span> <span class="kw">sizeof</span><span class="op">...(</span>Ts<span class="op">)</span> <span class="op">==</span> <span class="kw">sizeof</span><span class="op">...(</span>Us<span class="op">)</span></span>
<span id="cb1-20"><a href="#cb1-20"></a>              <span class="op">&amp;&amp;</span> <span class="op">(</span>is_constructible_v<span class="op">&lt;</span>Ts, Us <span class="kw">const</span><span class="op">&amp;&amp;&gt;</span> <span class="op">&amp;&amp;</span> <span class="op">...)</span></span>
<span id="cb1-21"><a href="#cb1-21"></a>    tuple<span class="op">(</span>tuple<span class="op">&lt;</span>Us<span class="op">...&gt;</span> <span class="kw">const</span><span class="op">&amp;&amp;)</span>;</span>
<span id="cb1-22"><a href="#cb1-22"></a><span class="op">}</span>;</span></code></pre></div>
</blockquote>
<p>This is pretty tedious to say the least. But it also has a subtle problem: these constructors are all <em>overloads</em> - which means that if the one you’d think would be called is valid, it is still possible for a different one to be invoked. For instance:</p>
<blockquote>
<div class="sourceCode" id="cb2"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb2-1"><a href="#cb2-1"></a><span class="dt">void</span> f<span class="op">(</span>tuple<span class="op">&lt;</span><span class="dt">int</span><span class="op">&amp;&gt;)</span>;</span>
<span id="cb2-2"><a href="#cb2-2"></a><span class="kw">auto</span> g<span class="op">()</span> <span class="op">-&gt;</span> tuple<span class="op">&lt;</span><span class="dt">int</span><span class="op">&amp;&amp;&gt;</span>;</span>
<span id="cb2-3"><a href="#cb2-3"></a></span>
<span id="cb2-4"><a href="#cb2-4"></a><span class="dt">void</span> h<span class="op">()</span> <span class="op">{</span></span>
<span id="cb2-5"><a href="#cb2-5"></a>    f<span class="op">(</span>g<span class="op">())</span>; <span class="co">// ok!</span></span>
<span id="cb2-6"><a href="#cb2-6"></a><span class="op">}</span></span></code></pre></div>
</blockquote>
<p>Here, we’re trying to construct a <code class="sourceCode cpp">tuple<span class="op">&lt;</span><span class="dt">int</span><span class="op">&amp;&gt;</span></code> from an <em>rvalue</em> <code class="sourceCode cpp">tuple<span class="op">&lt;</span><span class="dt">int</span><span class="op">&amp;&amp;&gt;</span></code>. The desired behavior is that the <code class="sourceCode cpp">tuple<span class="op">&lt;</span>Us<span class="op">...&gt;&amp;&amp;</span></code> is considered and then rejected (because <code class="sourceCode cpp"><span class="dt">int</span><span class="op">&amp;</span></code> is not constructible from <code class="sourceCode cpp">Us<span class="op">&amp;&amp;</span></code> - <code class="sourceCode cpp"><span class="dt">int</span><span class="op">&amp;&amp;</span></code>). That part indeed happens. But the <code class="sourceCode cpp">tuple<span class="op">&lt;</span>Us<span class="op">...&gt;</span> <span class="kw">const</span><span class="op">&amp;</span></code> constructor still exists and that one ends up being fine (because <code class="sourceCode cpp"><span class="dt">int</span><span class="op">&amp;</span></code> is constructible from <code class="sourceCode cpp">Us <span class="kw">const</span><span class="op">&amp;</span></code> - which is <code class="sourceCode cpp"><span class="dt">int</span><span class="op">&amp;</span></code> here). That’s surprising and undesirable.</p>
<p>But in order to avoid this, we’d need to only have a single constructor template. What we <em>want</em> is to have <em>some kind</em> of <code class="sourceCode cpp">tuple<span class="op">&lt;</span>Us<span class="op">...&gt;</span></code> and just deduce the <code class="sourceCode cpp"><em>cv</em> <em>ref</em></code> part. But our only choice today is either the code above (tedious, yet mostly functional, despite this problem) or to go full template:</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">template</span> <span class="op">&lt;</span><span class="kw">typename</span><span class="op">...</span> Ts<span class="op">&gt;</span></span>
<span id="cb3-2"><a href="#cb3-2"></a><span class="kw">struct</span> tuple <span class="op">{</span></span>
<span id="cb3-3"><a href="#cb3-3"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> Other<span class="op">&gt;</span></span>
<span id="cb3-4"><a href="#cb3-4"></a>        <span class="kw">requires</span> is_specialization_of<span class="op">&lt;</span>remove_cvref_t<span class="op">&lt;</span>Other<span class="op">&gt;</span>, tuple<span class="op">&gt;</span></span>
<span id="cb3-5"><a href="#cb3-5"></a>              <span class="op">&amp;&amp;</span> <span class="co">/* ???? */</span></span>
<span id="cb3-6"><a href="#cb3-6"></a>    tuple<span class="op">(</span>Other<span class="op">&amp;&amp;</span> rhs<span class="op">)</span>;</span>
<span id="cb3-7"><a href="#cb3-7"></a><span class="op">}</span>;</span></code></pre></div>
</blockquote>
<p>How do we write the rest of the constraint? We don’t really have a good way of doing so. Besides, for types which inherit from <code class="sourceCode cpp">std<span class="op">::</span>tuple</code>, this is now actually wrong - that derived type will not be a specialization of tuple, but rather instead inherit from one. We have to do extra work to get that part right, as we currently do in the <code class="sourceCode cpp">std<span class="op">::</span>visit</code> specification - see <span>22.6.7 <a href="https://wg21.link/variant.visit">[variant.visit]</a></span>/1.</p>
<h2 data-number="2.2" id="stdget-for-stdtuple"><span class="header-section-number">2.2</span> <code class="sourceCode cpp">std<span class="op">::</span>get</code> for <code class="sourceCode cpp">std<span class="op">::</span>tuple</code><a href="#stdget-for-stdtuple" class="self-link"></a></h2>
<p>We run into the same thing for non-member functions, where we want to have <code class="sourceCode cpp">std<span class="op">::</span>get<span class="op">&lt;</span>I<span class="op">&gt;</span></code> be invocable on every kind of tuple. Which today likewise has to be written:</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">template</span> <span class="op">&lt;</span><span class="dt">size_t</span> I, <span class="kw">typename</span><span class="op">...</span> Ts<span class="op">&gt;</span></span>
<span id="cb4-2"><a href="#cb4-2"></a><span class="kw">auto</span> get<span class="op">(</span>tuple<span class="op">&lt;</span>Ts<span class="op">...&gt;&amp;)</span> <span class="op">-&gt;</span> tuple_element_t<span class="op">&lt;</span>I, tuple<span class="op">&lt;</span>Ts<span class="op">...&gt;&gt;&amp;</span>;</span>
<span id="cb4-3"><a href="#cb4-3"></a></span>
<span id="cb4-4"><a href="#cb4-4"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="dt">size_t</span> I, <span class="kw">typename</span><span class="op">...</span> Ts<span class="op">&gt;</span></span>
<span id="cb4-5"><a href="#cb4-5"></a><span class="kw">auto</span> get<span class="op">(</span>tuple<span class="op">&lt;</span>Ts<span class="op">...&gt;</span> <span class="kw">const</span><span class="op">&amp;)</span> <span class="op">-&gt;</span> tuple_element_t<span class="op">&lt;</span>I, tuple<span class="op">&lt;</span>Ts<span class="op">...&gt;&gt;</span> <span class="kw">const</span><span class="op">&amp;</span>;</span>
<span id="cb4-6"><a href="#cb4-6"></a></span>
<span id="cb4-7"><a href="#cb4-7"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="dt">size_t</span> I, <span class="kw">typename</span><span class="op">...</span> Ts<span class="op">&gt;</span></span>
<span id="cb4-8"><a href="#cb4-8"></a><span class="kw">auto</span> get<span class="op">(</span>tuple<span class="op">&lt;</span>Ts<span class="op">...&gt;&amp;&amp;)</span> <span class="op">-&gt;</span> tuple_element_t<span class="op">&lt;</span>I, tuple<span class="op">&lt;</span>Ts<span class="op">...&gt;&gt;&amp;&amp;</span>;</span>
<span id="cb4-9"><a href="#cb4-9"></a></span>
<span id="cb4-10"><a href="#cb4-10"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="dt">size_t</span> I, <span class="kw">typename</span><span class="op">...</span> Ts<span class="op">&gt;</span></span>
<span id="cb4-11"><a href="#cb4-11"></a><span class="kw">auto</span> get<span class="op">(</span>tuple<span class="op">&lt;</span>Ts<span class="op">...&gt;</span> <span class="kw">const</span><span class="op">&amp;&amp;)</span> <span class="op">-&gt;</span> tuple_element_t<span class="op">&lt;</span>I, tuple<span class="op">&lt;</span>Ts<span class="op">...&gt;&gt;</span> <span class="kw">const</span><span class="op">&amp;&amp;</span>;</span></code></pre></div>
</blockquote>
<p>This one we could try to rewrite as a single function template, but in order to do that, we need to first coerce the type down to some kind of specialization of <code class="sourceCode cpp">tuple</code> - which ends up requiring a lot of the same work anyway.</p>
<h2 data-number="2.3" id="transform-for-stdoptional"><span class="header-section-number">2.3</span> <code class="sourceCode cpp">transform</code> for <code class="sourceCode cpp">std<span class="op">::</span>optional</code><a href="#transform-for-stdoptional" class="self-link"></a></h2>
<p>The previous two examples want to deduce to some specialization of a class template, this example wants to deduce to a specific type. One of the motivation examples from “deducing <code class="sourceCode cpp"><span class="kw">this</span></code>” was to remove the quadruplication necessary when writing a set of overloads that want to preserve <code class="sourceCode cpp"><span class="kw">const</span></code>-ness and value category. The adoption of <span class="citation" data-cites="P0798R8">[<a href="#ref-P0798R8" role="doc-biblioref">P0798R8</a>]</span> gives us several such examples.</p>
<p>In C++20, we’d write it as:</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">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span></span>
<span id="cb5-2"><a href="#cb5-2"></a><span class="kw">struct</span> optional <span class="op">{</span></span>
<span id="cb5-3"><a href="#cb5-3"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> F<span class="op">&gt;</span> <span class="kw">constexpr</span> <span class="kw">auto</span> transform<span class="op">(</span>F<span class="op">&amp;&amp;)</span> <span class="op">&amp;</span>;</span>
<span id="cb5-4"><a href="#cb5-4"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> F<span class="op">&gt;</span> <span class="kw">constexpr</span> <span class="kw">auto</span> transform<span class="op">(</span>F<span class="op">&amp;&amp;)</span> <span class="kw">const</span><span class="op">&amp;</span>;</span>
<span id="cb5-5"><a href="#cb5-5"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> F<span class="op">&gt;</span> <span class="kw">constexpr</span> <span class="kw">auto</span> transform<span class="op">(</span>F<span class="op">&amp;&amp;)</span> <span class="op">&amp;&amp;</span>;</span>
<span id="cb5-6"><a href="#cb5-6"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> F<span class="op">&gt;</span> <span class="kw">constexpr</span> <span class="kw">auto</span> transform<span class="op">(</span>F<span class="op">&amp;&amp;)</span> <span class="kw">const</span><span class="op">&amp;&amp;</span>;</span>
<span id="cb5-7"><a href="#cb5-7"></a><span class="op">}</span>;</span></code></pre></div>
</blockquote>
<p>complete with quadruplicating the body. But with deducing this, we might consider writing it as:</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">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span></span>
<span id="cb6-2"><a href="#cb6-2"></a><span class="kw">struct</span> optional <span class="op">{</span></span>
<span id="cb6-3"><a href="#cb6-3"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> Self, <span class="kw">typename</span> F<span class="op">&gt;</span> <span class="kw">constexpr</span> <span class="kw">auto</span> transform<span class="op">(</span><span class="kw">this</span> Self<span class="op">&amp;&amp;</span>, F<span class="op">&amp;&amp;)</span>;</span>
<span id="cb6-4"><a href="#cb6-4"></a><span class="op">}</span>;</span></code></pre></div>
</blockquote>
<p>But this deduces too much! We don’t want to deduce derived types (which in addition to unnecessary extra template instantiations, can also run into <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0847r7.html#the-shadowing-mitigation-private-inheritance-problem">shadowing issues</a>). We <em>just</em> want to know what the <code class="sourceCode cpp"><span class="kw">const</span></code>-ness and value category of the <code class="sourceCode cpp">optional</code> are. But the only solution at the moment is to C-style cast your way back down to your own type. And that’s not a particular popular solution, even amongst <a href="https://discourse.llvm.org/t/std-pmr-maturity/62200/17">standard library implementors</a>:</p>
<div class="quote">
<p>FWIW, we’re no longer using explicit object member functions for <code class="sourceCode cpp">std<span class="op">::</span>expected</code>; STL couldn’t stomach the necessary C-style cast without which the feature is not fit for purpose.</p>
</div>
<h2 data-number="2.4" id="view_interface-members"><span class="header-section-number">2.4</span> <code class="sourceCode cpp">view_interface</code> members<a href="#view_interface-members" class="self-link"></a></h2>
<p>Similar to the above, but even more specific, are the members for <code class="sourceCode cpp">view_interface</code> (see <span>26.5.3 <a href="https://wg21.link/view.interface">[view.interface]</a></span>). Currently, we have a bunch of pairs of member functions:</p>
<blockquote>
<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">template</span> <span class="op">&lt;</span><span class="kw">typename</span> D<span class="op">&gt;</span></span>
<span id="cb7-2"><a href="#cb7-2"></a><span class="kw">class</span> view_interface <span class="op">{</span></span>
<span id="cb7-3"><a href="#cb7-3"></a>    <span class="kw">constexpr</span> D<span class="op">&amp;</span> derived<span class="op">()</span> <span class="kw">noexcept</span> <span class="op">{</span> <span class="cf">return</span> <span class="kw">static_cast</span><span class="op">&lt;</span>D<span class="op">&amp;&gt;(*</span><span class="kw">this</span><span class="op">)</span>; <span class="op">}</span></span>
<span id="cb7-4"><a href="#cb7-4"></a>    <span class="kw">constexpr</span> D <span class="kw">const</span><span class="op">&amp;</span> derived<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span> <span class="op">{</span> <span class="cf">return</span> <span class="kw">static_cast</span><span class="op">&lt;</span>D <span class="kw">const</span><span class="op">&amp;&gt;(*</span><span class="kw">this</span><span class="op">)</span>; <span class="op">}</span></span>
<span id="cb7-5"><a href="#cb7-5"></a></span>
<span id="cb7-6"><a href="#cb7-6"></a><span class="kw">public</span><span class="op">:</span></span>
<span id="cb7-7"><a href="#cb7-7"></a>    <span class="kw">constexpr</span> <span class="dt">bool</span> empty<span class="op">()</span> <span class="kw">requires</span> forward_range<span class="op">&lt;</span>D<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb7-8"><a href="#cb7-8"></a>        <span class="cf">return</span> ranges<span class="op">::</span>begin<span class="op">(</span>derived<span class="op">())</span> <span class="op">==</span> ranges<span class="op">::</span>end<span class="op">(</span>derived<span class="op">())</span>;</span>
<span id="cb7-9"><a href="#cb7-9"></a>    <span class="op">}</span></span>
<span id="cb7-10"><a href="#cb7-10"></a>    <span class="kw">constexpr</span> <span class="dt">bool</span> empty<span class="op">()</span> <span class="kw">const</span> <span class="kw">requires</span> forward_range<span class="op">&lt;</span>D <span class="kw">const</span><span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb7-11"><a href="#cb7-11"></a>        <span class="cf">return</span> ranges<span class="op">::</span>begin<span class="op">(</span>derived<span class="op">())</span> <span class="op">==</span> ranges<span class="op">::</span>end<span class="op">(</span>derived<span class="op">())</span>;</span>
<span id="cb7-12"><a href="#cb7-12"></a>    <span class="op">}</span></span>
<span id="cb7-13"><a href="#cb7-13"></a><span class="op">}</span>;</span></code></pre></div>
</blockquote>
<p>With deducing this, we could write this as a single function template - deducing the self parameter such that it ends up being the derived type. But that’s again deducing way too much, when all we want to do is know if we’re a <code class="sourceCode cpp">D<span class="op">&amp;</span></code> or a <code class="sourceCode cpp">D <span class="kw">const</span><span class="op">&amp;</span></code>. But we can’t deduce just <code class="sourceCode cpp"><span class="kw">const</span></code>-ness.</p>
<h2 data-number="2.5" id="the-goal"><span class="header-section-number">2.5</span> The Goal<a href="#the-goal" class="self-link"></a></h2>
<p>To be more concrete, the goal here is to be able to specify a particular type or a particular class template such that template deduction will <em>just</em> deduce the <code class="sourceCode cpp"><span class="kw">const</span></code>-ness and value category, while also (where relevant) performing a derived-to-base conversion. That is, I want to be able to implement a single function template for <code class="sourceCode cpp">optional<span class="op">&lt;</span>T<span class="op">&gt;::</span>transform</code> such that if I invoke it with an rvalue of type <code class="sourceCode cpp">D</code> that inherits publicly and unambiguously from <code class="sourceCode cpp">optional<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;</span></code>, the function template will be instantiated with a first parameter of <code class="sourceCode cpp">optional<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;&amp;&amp;</span></code> (not <code class="sourceCode cpp">D<span class="op">&amp;&amp;</span></code>).</p>
<p>Put differently, and focused more on the desired solution criteria, the goal is to be able to define this (to be clear, the syntax <code class="sourceCode cpp"><em>some-kind-of</em></code> is just a placeholder):</p>
<blockquote>
<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">template</span> <span class="op">&lt;</span><span class="kw">class</span> T<span class="op">&gt;</span> <span class="kw">struct</span> Base <span class="op">{</span> <span class="op">}</span>;</span>
<span id="cb8-2"><a href="#cb8-2"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> T<span class="op">&gt;</span> <span class="kw">struct</span> Derived <span class="op">:</span> Base<span class="op">&lt;</span>T<span class="op">&gt;</span> <span class="op">{</span> <span class="op">}</span>;</span>
<span id="cb8-3"><a href="#cb8-3"></a></span>
<span id="cb8-4"><a href="#cb8-4"></a><span class="dt">void</span> f<span class="op">(</span><em>some-kind-of</em><span class="op">(</span>Base<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;)</span> x<span class="op">)</span> <span class="op">{</span></span>
<span id="cb8-5"><a href="#cb8-5"></a>  std<span class="op">::</span>println<span class="op">(</span><span class="st">&quot;Type of x is {}&quot;</span>, name_of<span class="op">(</span>type_of<span class="op">(^</span>x<span class="op">)))</span>;</span>
<span id="cb8-6"><a href="#cb8-6"></a><span class="op">}</span></span>
<span id="cb8-7"><a href="#cb8-7"></a></span>
<span id="cb8-8"><a href="#cb8-8"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> T<span class="op">&gt;</span></span>
<span id="cb8-9"><a href="#cb8-9"></a><span class="dt">void</span> g<span class="op">(</span><em>some-kind-of</em><span class="op">(</span>Base<span class="op">&lt;</span>T<span class="op">&gt;)</span> y<span class="op">)</span> <span class="op">{</span></span>
<span id="cb8-10"><a href="#cb8-10"></a>  std<span class="op">::</span>println<span class="op">(</span><span class="st">&quot;Type of y is {}&quot;</span>, name_of<span class="op">(</span>type_of<span class="op">(^</span>y<span class="op">)))</span>;</span>
<span id="cb8-11"><a href="#cb8-11"></a><span class="op">}</span></span>
<span id="cb8-12"><a href="#cb8-12"></a></span>
<span id="cb8-13"><a href="#cb8-13"></a><span class="dt">int</span> main<span class="op">()</span> <span class="op">{</span></span>
<span id="cb8-14"><a href="#cb8-14"></a>  Base<span class="op">&lt;</span><span class="dt">char</span><span class="op">&gt;</span> bc;</span>
<span id="cb8-15"><a href="#cb8-15"></a>  Base<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;</span> bi;</span>
<span id="cb8-16"><a href="#cb8-16"></a>  Derived<span class="op">&lt;</span><span class="dt">char</span><span class="op">&gt;</span> dc;</span>
<span id="cb8-17"><a href="#cb8-17"></a>  Derived<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;</span> di;</span>
<span id="cb8-18"><a href="#cb8-18"></a></span>
<span id="cb8-19"><a href="#cb8-19"></a>  f<span class="op">(</span>bi<span class="op">)</span>;                <span class="co">// prints: Type of x is Base&lt;int&gt;&amp;</span></span>
<span id="cb8-20"><a href="#cb8-20"></a>  f<span class="op">(</span>di<span class="op">)</span>;                <span class="co">// prints: Type of x is Base&lt;int&amp;&gt;</span></span>
<span id="cb8-21"><a href="#cb8-21"></a>  f<span class="op">(</span>std<span class="op">::</span>move<span class="op">(</span>di<span class="op">))</span>;     <span class="co">// prints: Type of x is Base&lt;int&gt;&amp;&amp;</span></span>
<span id="cb8-22"><a href="#cb8-22"></a></span>
<span id="cb8-23"><a href="#cb8-23"></a>  g<span class="op">(</span>bc<span class="op">)</span>;                <span class="co">// deduces T=char, prints: Type of y is Base&lt;char&gt;&amp;</span></span>
<span id="cb8-24"><a href="#cb8-24"></a>  g<span class="op">(</span>std<span class="op">::</span>move<span class="op">(</span>dc<span class="op">))</span>;     <span class="co">// deduces T=char, prints: Type of y is Base&lt;char&gt;&amp;&amp;</span></span>
<span id="cb8-25"><a href="#cb8-25"></a>  g<span class="op">(</span>std<span class="op">::</span>as_const<span class="op">(</span>di<span class="op">))</span>; <span class="co">// deduces T=int, prints: Type of y is Base&lt;int&gt; const&amp;</span></span>
<span id="cb8-26"><a href="#cb8-26"></a><span class="op">}</span></span></code></pre></div>
</blockquote>
<p>Two important things to keep in mind here:</p>
<ul>
<li><code class="sourceCode cpp">f</code> and <code class="sourceCode cpp">g</code> are both function templates</li>
<li>The types of the parameters <code class="sourceCode cpp">x</code> and <code class="sourceCode cpp">y</code> are always some kind of <code class="sourceCode cpp">Base</code>, even if we pass in a <code class="sourceCode cpp">Derived</code>.</li>
</ul>
<h1 data-number="3" style="border-bottom:1px solid #cccccc" id="the-ideas"><span class="header-section-number">3</span> The Ideas<a href="#the-ideas" class="self-link"></a></h1>
<p>There were several ideas suggested in the previous revision that fit the EWG-preferred criteria of “a new forwarding reference syntax”. Let’s quickly run through them and see how they stack up.</p>
<h2 data-number="3.1" id="t-auto"><span class="header-section-number">3.1</span> <code class="sourceCode cpp">T <span class="kw">auto</span><span class="op">&amp;&amp;</span></code><a href="#t-auto" class="self-link"></a></h2>
<p>The principle here is that in the same say that <code class="sourceCode cpp">range <span class="kw">auto</span><span class="op">&amp;&amp;</span></code>is some kind of <code class="sourceCode cpp">range</code>, that <code class="sourceCode cpp"><span class="dt">int</span> <span class="kw">auto</span><span class="op">&amp;&amp;</span></code> is some kind of <code class="sourceCode cpp"><span class="dt">int</span></code>. It kind of makes sense, kind of doesn’t. Depends on how you think about it.</p>
<table>
<tr>
<th>
<code class="sourceCode cpp">tuple</code>
</th>
<td>
<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">template</span> <span class="op">&lt;</span><span class="kw">typename</span><span class="op">...</span> Ts<span class="op">&gt;</span></span>
<span id="cb9-2"><a href="#cb9-2"></a><span class="kw">struct</span> tuple <span class="op">{</span></span>
<span id="cb9-3"><a href="#cb9-3"></a>  <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span><span class="op">...</span> Us<span class="op">&gt;</span></span>
<span id="cb9-4"><a href="#cb9-4"></a>  tuple<span class="op">(</span>tuple<span class="op">&lt;</span>Us<span class="op">...&gt;</span> <span class="kw">auto</span><span class="op">&amp;&amp;</span> rhs<span class="op">)</span></span>
<span id="cb9-5"><a href="#cb9-5"></a>    <span class="kw">requires</span> <span class="kw">sizeof</span><span class="op">...(</span>Us<span class="op">)</span> <span class="op">==</span> <span class="kw">sizeof</span><span class="op">...(</span>Ts<span class="op">)</span></span>
<span id="cb9-6"><a href="#cb9-6"></a>          <span class="op">&amp;&amp;</span> <span class="op">(</span>constructible_from<span class="op">&lt;</span></span>
<span id="cb9-7"><a href="#cb9-7"></a>                Ts,</span>
<span id="cb9-8"><a href="#cb9-8"></a>                copy_cvref_t<span class="op">&lt;</span><span class="kw">decltype</span><span class="op">(</span>rhs<span class="op">)</span>, Us<span class="op">&gt;</span></span>
<span id="cb9-9"><a href="#cb9-9"></a>              <span class="op">&gt;</span> <span class="op">&amp;&amp;</span> <span class="op">...)</span>;</span>
<span id="cb9-10"><a href="#cb9-10"></a><span class="op">}</span>;</span></code></pre></div>
</td>
</tr>
<tr>
<th>
<code class="sourceCode cpp">optional</code>
</th>
<td>
<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">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span></span>
<span id="cb10-2"><a href="#cb10-2"></a><span class="kw">struct</span> optional <span class="op">{</span></span>
<span id="cb10-3"><a href="#cb10-3"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> F<span class="op">&gt;</span></span>
<span id="cb10-4"><a href="#cb10-4"></a>    <span class="kw">auto</span> transform<span class="op">(</span><span class="kw">this</span> optional <span class="kw">auto</span><span class="op">&amp;&amp;</span> self, F<span class="op">&amp;&amp;</span> f<span class="op">)</span> <span class="op">{</span></span>
<span id="cb10-5"><a href="#cb10-5"></a>        <span class="kw">using</span> U <span class="op">=</span> remove_cv_t<span class="op">&lt;</span>invoke_result_t<span class="op">&lt;</span>F,</span>
<span id="cb10-6"><a href="#cb10-6"></a>            <span class="kw">decltype</span><span class="op">(</span>FWD<span class="op">(</span>self<span class="op">).</span>value<span class="op">())&gt;</span>;</span>
<span id="cb10-7"><a href="#cb10-7"></a></span>
<span id="cb10-8"><a href="#cb10-8"></a>        <span class="cf">if</span> <span class="op">(</span>self<span class="op">)</span> <span class="op">{</span></span>
<span id="cb10-9"><a href="#cb10-9"></a>          <span class="cf">return</span> optional<span class="op">&lt;</span>U<span class="op">&gt;(</span>invoke<span class="op">(</span>FWD<span class="op">(</span>f<span class="op">)</span>, FWD<span class="op">(</span>self<span class="op">).</span>value<span class="op">()))</span>;</span>
<span id="cb10-10"><a href="#cb10-10"></a>        <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb10-11"><a href="#cb10-11"></a>          <span class="cf">return</span> optional<span class="op">&lt;</span>U<span class="op">&gt;()</span>;</span>
<span id="cb10-12"><a href="#cb10-12"></a>        <span class="op">}</span></span>
<span id="cb10-13"><a href="#cb10-13"></a>    <span class="op">}</span></span>
<span id="cb10-14"><a href="#cb10-14"></a><span class="op">}</span>;</span></code></pre></div>
</td>
</tr>
<tr>
<th>
<code class="sourceCode cpp">view_interface</code>
</th>
<td>
<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">template</span> <span class="op">&lt;</span><span class="kw">typename</span> D<span class="op">&gt;</span></span>
<span id="cb11-2"><a href="#cb11-2"></a><span class="kw">struct</span> view_interface <span class="op">{</span></span>
<span id="cb11-3"><a href="#cb11-3"></a>    <span class="kw">constexpr</span> <span class="dt">bool</span> empty<span class="op">(</span><span class="kw">this</span> D <span class="kw">auto</span><span class="op">&amp;</span> self<span class="op">)</span></span>
<span id="cb11-4"><a href="#cb11-4"></a>        <span class="kw">requires</span> forward_range<span class="op">&lt;</span><span class="kw">decltype</span><span class="op">(</span>self<span class="op">)&gt;</span></span>
<span id="cb11-5"><a href="#cb11-5"></a>    <span class="op">{</span></span>
<span id="cb11-6"><a href="#cb11-6"></a>        <span class="cf">return</span> ranges<span class="op">::</span>begin<span class="op">(</span>self<span class="op">)</span> <span class="op">==</span> ranges<span class="op">::</span>end<span class="op">(</span>self<span class="op">)</span>;</span>
<span id="cb11-7"><a href="#cb11-7"></a>    <span class="op">}</span></span>
<span id="cb11-8"><a href="#cb11-8"></a><span class="op">}</span>;</span></code></pre></div>
</td>
</tr>
</table>
<p>The advantage of this syntax is that it’s concise and lets you do what you need to do.</p>
<p>The disadvantage of this syntax is that the only way you can get the type is by writing <code class="sourceCode cpp"><span class="kw">decltype</span><span class="op">(</span>param<span class="op">)</span></code> - and the only way to can pass through the <code class="sourceCode cpp"><span class="kw">const</span></code>-ness and qualifiers is by grabbing them off of <code class="sourceCode cpp"><span class="kw">decltype</span><span class="op">(</span>param<span class="op">)</span></code>. That’s fine if the type itself is all that is necessary (as it the case for <code class="sourceCode cpp">view_interface</code>) but not so much when you actually need to apply them (as is the case for <code class="sourceCode cpp">tuple</code>). This also means that the only place you can put the <code class="sourceCode cpp"><span class="kw">requires</span></code> clause is after the parameters. Another disadvantage is that the derived-to-base conversion aspect of this makes it inconsistent with what <code class="sourceCode cpp">Concept <span class="kw">auto</span></code> actually means - which is not actually doing any conversion.</p>
<h2 data-number="3.2" id="t"><span class="header-section-number">3.2</span> <code class="sourceCode cpp">T<span class="op">&amp;&amp;&amp;</span></code><a href="#t" class="self-link"></a></h2>
<p>Rather than writing <code class="sourceCode cpp">tuple<span class="op">&lt;</span>U<span class="op">...&gt;</span> <span class="kw">auto</span><span class="op">&amp;&amp;</span> rhs</code> we can instead introduce a new kind of reference and spell it <code class="sourceCode cpp">tuple<span class="op">&lt;</span>U<span class="op">...&gt;&amp;&amp;&amp;</span> rhs</code>. This syntactically looks nearly the same as the <code class="sourceCode cpp">T <span class="kw">auto</span><span class="op">&amp;&amp;</span></code> version, so I’m not going to copy it.</p>
<p>If we went this route, we would naturally have to also allow:</p>
<blockquote>
<div class="sourceCode" id="cb12"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb12-1"><a href="#cb12-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span> <span class="dt">void</span> f<span class="op">(</span>T<span class="op">&amp;&amp;)</span>;  <span class="co">// regular forwarding reference</span></span>
<span id="cb12-2"><a href="#cb12-2"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span> <span class="dt">void</span> g<span class="op">(</span>T<span class="op">&amp;&amp;&amp;)</span>; <span class="co">// also regular forwarding reference</span></span></code></pre></div>
</blockquote>
<p>The advantage here is that it’s less arguably broken than the previous version, since it’s more reasonable that the <code class="sourceCode cpp">tuple<span class="op">&lt;</span>U<span class="op">...&gt;&amp;&amp;&amp;</span></code> syntax would allow derived-to-base conversion.</p>
<p>But the problem with this syntax is what it would mean in the case where we wanted a forwarding reference to a specific type:</p>
<blockquote>
<div class="sourceCode" id="cb13"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb13-1"><a href="#cb13-1"></a><span class="co">// this is a function taking an rvalue reference to string</span></span>
<span id="cb13-2"><a href="#cb13-2"></a><span class="dt">void</span> f<span class="op">(</span>string<span class="op">&amp;&amp;</span> x<span class="op">)</span>;</span>
<span id="cb13-3"><a href="#cb13-3"></a></span>
<span id="cb13-4"><a href="#cb13-4"></a><span class="co">// this is a function template taking a forwarding reference to string</span></span>
<span id="cb13-5"><a href="#cb13-5"></a><span class="dt">void</span> g<span class="op">(</span>string<span class="op">&amp;&amp;&amp;</span> x<span class="op">)</span>;</span></code></pre></div>
</blockquote>
<p>That visually-negligible difference makes this a complete non-starter. Yes, it’s technically <em>distinct</em> in the same way that <code class="sourceCode cpp">Concept <span class="kw">auto</span></code> is visually distinct from <code class="sourceCode cpp">Type</code> and a compiler would have no trouble doing the correct thing in this situation, but the <code class="sourceCode cpp"><span class="kw">auto</span></code> there really helps readability a lot and having a third <code class="sourceCode cpp"><span class="op">&amp;</span></code> be the distinguishing marker is just far too subtle in a language that has a lot of <code class="sourceCode cpp"><span class="op">&amp;</span></code>s already.</p>
<h2 data-number="3.3" id="forward-t"><span class="header-section-number">3.3</span> <code class="sourceCode cpp">forward T</code><a href="#forward-t" class="self-link"></a></h2>
<p>This is not a syntax that has previously appeared in the paper, but the idea is:</p>
<blockquote>
<div class="sourceCode" id="cb14"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb14-1"><a href="#cb14-1"></a><span class="co">// this is a function template taking a forwarding reference to string</span></span>
<span id="cb14-2"><a href="#cb14-2"></a><span class="dt">void</span> f<span class="op">(</span>forward string x<span class="op">)</span>;</span>
<span id="cb14-3"><a href="#cb14-3"></a></span>
<span id="cb14-4"><a href="#cb14-4"></a><span class="co">// these declarations are equivalent in what they accept</span></span>
<span id="cb14-5"><a href="#cb14-5"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span> <span class="dt">void</span> g<span class="op">(</span>forward T x<span class="op">)</span>;</span>
<span id="cb14-6"><a href="#cb14-6"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> U<span class="op">&gt;</span> <span class="dt">void</span> h<span class="op">(</span>U<span class="op">&amp;&amp;</span> y<span class="op">)</span>;</span></code></pre></div>
</blockquote>
<p>Otherwise usage is similar to the <code class="sourceCode cpp">T <span class="kw">auto</span><span class="op">&amp;&amp;</span></code> syntax <a href="#t-auto">above</a>:</p>
<table>
<tr>
<th>
<code class="sourceCode cpp">tuple</code>
</th>
<td>
<div class="sourceCode" id="cb15"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb15-1"><a href="#cb15-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span><span class="op">...</span> Ts<span class="op">&gt;</span></span>
<span id="cb15-2"><a href="#cb15-2"></a><span class="kw">struct</span> tuple <span class="op">{</span></span>
<span id="cb15-3"><a href="#cb15-3"></a>  <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span><span class="op">...</span> Us<span class="op">&gt;</span></span>
<span id="cb15-4"><a href="#cb15-4"></a>  tuple<span class="op">(</span>forward tuple<span class="op">&lt;</span>Us<span class="op">...&gt;</span> rhs<span class="op">)</span></span>
<span id="cb15-5"><a href="#cb15-5"></a>    <span class="kw">requires</span> <span class="kw">sizeof</span><span class="op">...(</span>Us<span class="op">)</span> <span class="op">==</span> <span class="kw">sizeof</span><span class="op">...(</span>Ts<span class="op">)</span></span>
<span id="cb15-6"><a href="#cb15-6"></a>          <span class="op">&amp;&amp;</span> <span class="op">(</span>constructible_from<span class="op">&lt;</span></span>
<span id="cb15-7"><a href="#cb15-7"></a>                Ts,</span>
<span id="cb15-8"><a href="#cb15-8"></a>                copy_cvref_t<span class="op">&lt;</span><span class="kw">decltype</span><span class="op">(</span>rhs<span class="op">)</span>, Us<span class="op">&gt;</span></span>
<span id="cb15-9"><a href="#cb15-9"></a>              <span class="op">&gt;</span> <span class="op">&amp;&amp;</span> <span class="op">...)</span>;</span>
<span id="cb15-10"><a href="#cb15-10"></a><span class="op">}</span>;</span></code></pre></div>
</td>
</tr>
<tr>
<th>
<code class="sourceCode cpp">optional</code>
</th>
<td>
<div class="sourceCode" id="cb16"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb16-1"><a href="#cb16-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span></span>
<span id="cb16-2"><a href="#cb16-2"></a><span class="kw">struct</span> optional <span class="op">{</span></span>
<span id="cb16-3"><a href="#cb16-3"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> F<span class="op">&gt;</span></span>
<span id="cb16-4"><a href="#cb16-4"></a>    <span class="kw">auto</span> transform<span class="op">(</span><span class="kw">this</span> forward optional self, F<span class="op">&amp;&amp;</span> f<span class="op">)</span> <span class="op">{</span></span>
<span id="cb16-5"><a href="#cb16-5"></a>        <span class="kw">using</span> U <span class="op">=</span> remove_cv_t<span class="op">&lt;</span>invoke_result_t<span class="op">&lt;</span>F,</span>
<span id="cb16-6"><a href="#cb16-6"></a>            <span class="kw">decltype</span><span class="op">(</span>FWD<span class="op">(</span>self<span class="op">).</span>value<span class="op">())&gt;</span>;</span>
<span id="cb16-7"><a href="#cb16-7"></a></span>
<span id="cb16-8"><a href="#cb16-8"></a>        <span class="cf">if</span> <span class="op">(</span>self<span class="op">)</span> <span class="op">{</span></span>
<span id="cb16-9"><a href="#cb16-9"></a>          <span class="cf">return</span> optional<span class="op">&lt;</span>U<span class="op">&gt;(</span>invoke<span class="op">(</span>FWD<span class="op">(</span>f<span class="op">)</span>, FWD<span class="op">(</span>self<span class="op">).</span>value<span class="op">()))</span>;</span>
<span id="cb16-10"><a href="#cb16-10"></a>        <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb16-11"><a href="#cb16-11"></a>          <span class="cf">return</span> optional<span class="op">&lt;</span>U<span class="op">&gt;()</span>;</span>
<span id="cb16-12"><a href="#cb16-12"></a>        <span class="op">}</span></span>
<span id="cb16-13"><a href="#cb16-13"></a>    <span class="op">}</span></span>
<span id="cb16-14"><a href="#cb16-14"></a><span class="op">}</span>;</span></code></pre></div>
</td>
</tr>
<tr>
<th>
<code class="sourceCode cpp">view_interface</code>
</th>
<td>
<div class="sourceCode" id="cb17"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb17-1"><a href="#cb17-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> D<span class="op">&gt;</span></span>
<span id="cb17-2"><a href="#cb17-2"></a><span class="kw">struct</span> view_interface <span class="op">{</span></span>
<span id="cb17-3"><a href="#cb17-3"></a>    <span class="kw">constexpr</span> <span class="dt">bool</span> empty<span class="op">(</span><span class="kw">this</span> forward D<span class="op">&amp;</span> self<span class="op">)</span></span>
<span id="cb17-4"><a href="#cb17-4"></a>        <span class="kw">requires</span> forward_range<span class="op">&lt;</span><span class="kw">decltype</span><span class="op">(</span>self<span class="op">)&gt;</span></span>
<span id="cb17-5"><a href="#cb17-5"></a>    <span class="op">{</span></span>
<span id="cb17-6"><a href="#cb17-6"></a>        <span class="cf">return</span> ranges<span class="op">::</span>begin<span class="op">(</span>self<span class="op">)</span> <span class="op">==</span> ranges<span class="op">::</span>end<span class="op">(</span>self<span class="op">)</span>;</span>
<span id="cb17-7"><a href="#cb17-7"></a>    <span class="op">}</span></span>
<span id="cb17-8"><a href="#cb17-8"></a><span class="op">}</span>;</span></code></pre></div>
</td>
</tr>
</table>
<p>Both <code class="sourceCode cpp">forward T x</code> and <code class="sourceCode cpp">T <span class="kw">auto</span><span class="op">&amp;&amp;</span> x</code> have the issue that there’s no way to name the actual type of the parameter <code class="sourceCode cpp">x</code> other than <code class="sourceCode cpp"><span class="kw">decltype</span><span class="op">(</span>x<span class="op">)</span></code>. The advantage of <code class="sourceCode cpp">forward T x</code> is that, as a novel syntax, the fact that it behaves differently from <code class="sourceCode cpp">Concept <span class="kw">auto</span></code> is… fine - it’s a different syntax, so it is unsurprising that it would behave differently.</p>
<p>The disadvantage of <code class="sourceCode cpp">forward T x</code> is that it’s a novel syntax - would require a contextually sensitive keyword <code class="sourceCode cpp">forward</code>:</p>
<blockquote>
<div class="sourceCode" id="cb18"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb18-1"><a href="#cb18-1"></a><span class="kw">struct</span> forward <span class="op">{</span> <span class="op">}</span>;</span>
<span id="cb18-2"><a href="#cb18-2"></a><span class="kw">struct</span> string <span class="op">{</span> <span class="op">}</span>;</span>
<span id="cb18-3"><a href="#cb18-3"></a></span>
<span id="cb18-4"><a href="#cb18-4"></a><span class="co">// function taking a parameter of type forward named string</span></span>
<span id="cb18-5"><a href="#cb18-5"></a><span class="dt">void</span> f<span class="op">(</span>forward string<span class="op">)</span>;</span>
<span id="cb18-6"><a href="#cb18-6"></a></span>
<span id="cb18-7"><a href="#cb18-7"></a><span class="co">// function taking a forwarding reference of type string named _</span></span>
<span id="cb18-8"><a href="#cb18-8"></a><span class="dt">void</span> g<span class="op">(</span>forward string _<span class="op">)</span>;</span></code></pre></div>
</blockquote>
<p>But this probably isn’t a huge problem - since</p>
<ol type="a">
<li><code class="sourceCode cpp">forward</code> isn’t a terribly common name for a type</li>
<li>the actual type would have to be a valid identifier in its own right (so no qualified names or template specializations), and</li>
<li>you’re never going to write such a function template without actually wanting to use the parameter, so you’re not going to forget to name it.</li>
</ol>
<p>So while the novelty is certainly a disadvantage, the potential misuse/clash with existing syntax does not strike me as a big concern.</p>
<p>Note that Herb Sutter’s <a href="https://github.com/hsutter/cppfront">CppFront</a> has parameter labels, one of which is <code class="sourceCode cpp">forward</code>. You can declare a CppFront function template as:</p>
<table>
<thead>
<tr class="header">
<th><div style="text-align:center">
<strong>CppFront</strong>
</div></th>
<th><div style="text-align:center">
<strong>C++</strong>
</div></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><div class="sourceCode" id="cb19"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb19-1"><a href="#cb19-1"></a>decorate<span class="op">:</span> <span class="op">(</span>forward s<span class="op">:</span> std<span class="op">::</span>string<span class="op">)</span> <span class="op">=</span> <span class="op">{</span></span>
<span id="cb19-2"><a href="#cb19-2"></a>    s <span class="op">=</span> <span class="st">&quot;[&quot;</span> <span class="op">+</span> s <span class="op">+</span> <span class="st">&quot;]&quot;</span>;</span>
<span id="cb19-3"><a href="#cb19-3"></a><span class="op">}</span></span></code></pre></div></td>
<td><div class="sourceCode" id="cb20"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb20-1"><a href="#cb20-1"></a><span class="kw">auto</span> decorate<span class="op">(</span><span class="kw">auto</span><span class="op">&amp;&amp;</span> s<span class="op">)</span> <span class="op">-&gt;</span> <span class="dt">void</span></span>
<span id="cb20-2"><a href="#cb20-2"></a><span class="kw">requires</span> <span class="op">(</span>std<span class="op">::</span>is_same_v<span class="op">&lt;</span>CPP2_TYPEOF<span class="op">(</span>s<span class="op">)</span>, std<span class="op">::</span>string<span class="op">&gt;)</span> <span class="op">{</span></span>
<span id="cb20-3"><a href="#cb20-3"></a>    s <span class="op">=</span> <span class="st">&quot;[&quot;</span> <span class="op">+</span> CPP2_FORWARD<span class="op">(</span>s<span class="op">)</span> <span class="op">+</span> <span class="st">&quot;]&quot;</span>;</span>
<span id="cb20-4"><a href="#cb20-4"></a><span class="op">}</span></span></code></pre></div></td>
</tr>
</tbody>
</table>
<p>The CppFront code on the left compiles into the C++ code on the right. This seems equivalent, but there are two important differences between the CppFront feature and what’s suggested here:</p>
<ol type="1">
<li>CppFront’s declaration requires the argument to be exactly some kind of <code class="sourceCode cpp">std<span class="op">::</span>string</code>, not any derived type. But this proposal needs <code class="sourceCode cpp">forward std<span class="op">::</span>string s</code> to accept any type derived from <code class="sourceCode cpp">std<span class="op">::</span>string</code> and also coerce it to be a <code class="sourceCode cpp">std<span class="op">::</span>string</code> such that the parameter is always some kind of <code class="sourceCode cpp">std<span class="op">::</span>string</code>.</li>
<li>CppFront’s <code class="sourceCode cpp">forward</code> parameters forward on definite last use.</li>
</ol>
<ol start="2" type="1">
<li>is actually a pretty useful aspect in its own right, since it allows you to annotate a <code class="sourceCode cpp">forward</code> parameter and not have to annotate the body - although it doesn’t actually save you many characters. But (1) is the important difference - accepting derived types and coercing to base is the key aspect to this proposal.</li>
</ol>
<h2 data-number="3.4" id="non-forward-reference-syntaxes"><span class="header-section-number">3.4</span> Non-forward reference syntaxes<a href="#non-forward-reference-syntaxes" class="self-link"></a></h2>
<p>For completeness, the previous revision had ideas for <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2481r1.html#constbool">deducing <code class="sourceCode cpp"><span class="kw">const</span></code></a>, a new kind of <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2481r1.html#qualifiers-q">qualifier deduction</a>, and Circle’s approach of a new kind of <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2481r1.html#circles-approach">parameter annotation</a>.</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>There are only really two viable syntaxes I’ve come up with for how to solve this problem that are some kind of “new forwarding reference syntax”:</p>
<table>
<thead>
<tr class="header">
<th><div style="text-align:center">
<strong><code class="sourceCode cpp">T <span class="kw">auto</span><span class="op">&amp;&amp;</span> x</code></strong>
</div></th>
<th><div style="text-align:center">
<strong><code class="sourceCode cpp">forward T x</code></strong>
</div></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><div class="sourceCode" id="cb21"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb21-1"><a href="#cb21-1"></a><span class="dt">void</span> f<span class="op">(</span>std<span class="op">::</span>string <span class="kw">auto</span><span class="op">&amp;&amp;</span> a<span class="op">)</span>;</span>
<span id="cb21-2"><a href="#cb21-2"></a></span>
<span id="cb21-3"><a href="#cb21-3"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span><span class="op">...</span> Ts<span class="op">&gt;</span></span>
<span id="cb21-4"><a href="#cb21-4"></a><span class="dt">void</span> g<span class="op">(</span>std<span class="op">::</span>tuple<span class="op">&lt;</span>Ts<span class="op">...&gt;</span> <span class="kw">auto</span><span class="op">&amp;&amp;</span> b<span class="op">)</span>;</span>
<span id="cb21-5"><a href="#cb21-5"></a></span>
<span id="cb21-6"><a href="#cb21-6"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span></span>
<span id="cb21-7"><a href="#cb21-7"></a><span class="dt">void</span> h<span class="op">(</span>T <span class="kw">auto</span><span class="op">&amp;&amp;</span> c<span class="op">)</span>;</span>
<span id="cb21-8"><a href="#cb21-8"></a></span>
<span id="cb21-9"><a href="#cb21-9"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span></span>
<span id="cb21-10"><a href="#cb21-10"></a><span class="dt">void</span> i<span class="op">(</span>T <span class="kw">auto</span><span class="op">&amp;</span> d<span class="op">)</span>;</span></code></pre></div></td>
<td><div class="sourceCode" id="cb22"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb22-1"><a href="#cb22-1"></a><span class="dt">void</span> f<span class="op">(</span>forward std<span class="op">::</span>string a<span class="op">)</span>;</span>
<span id="cb22-2"><a href="#cb22-2"></a></span>
<span id="cb22-3"><a href="#cb22-3"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span><span class="op">...</span> Ts<span class="op">&gt;</span></span>
<span id="cb22-4"><a href="#cb22-4"></a><span class="dt">void</span> g<span class="op">(</span>forward std<span class="op">::</span>tuple<span class="op">&lt;</span>Ts<span class="op">...&gt;</span> b<span class="op">)</span>;</span>
<span id="cb22-5"><a href="#cb22-5"></a></span>
<span id="cb22-6"><a href="#cb22-6"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span></span>
<span id="cb22-7"><a href="#cb22-7"></a><span class="dt">void</span> h<span class="op">(</span>forward T c<span class="op">)</span>;</span>
<span id="cb22-8"><a href="#cb22-8"></a></span>
<span id="cb22-9"><a href="#cb22-9"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span></span>
<span id="cb22-10"><a href="#cb22-10"></a><span class="dt">void</span> i<span class="op">(</span>forward T<span class="op">&amp;</span> d<span class="op">)</span>;</span></code></pre></div></td>
</tr>
</tbody>
</table>
<p>These are all function template declarations:</p>
<ul>
<li><code class="sourceCode cpp">f</code> takes a forwarding reference to <code class="sourceCode cpp">std<span class="op">::</span>string</code> (<code class="sourceCode cpp">a</code> is always some kind of <code class="sourceCode cpp">std<span class="op">::</span>string <em>cv</em> <em>ref</em></code>). Types derived from <code class="sourceCode cpp">std<span class="op">::</span>string</code> undergo derived-to-base conversion first.</li>
<li><code class="sourceCode cpp">g</code> takes a forwarding reference to some kind of <code class="sourceCode cpp">std<span class="op">::</span>tuple<span class="op">&lt;</span>Ts<span class="op">...&gt;</span></code>, deducing <code class="sourceCode cpp">Ts<span class="op">...</span></code>.</li>
<li><code class="sourceCode cpp">h</code> takes a forwarding to any type. Here, if I pass an lvalue of type <code class="sourceCode cpp"><span class="dt">int</span></code>, while <code class="sourceCode cpp"><span class="kw">decltype</span><span class="op">(</span>c<span class="op">)</span></code> will be <code class="sourceCode cpp"><span class="dt">int</span><span class="op">&amp;</span></code>, <code class="sourceCode cpp">T</code> will deduce as <code class="sourceCode cpp"><span class="dt">int</span></code>.</li>
<li><code class="sourceCode cpp">i</code> takes a forwarding reference to any type, but only accepts lvalues. Passing an rvalue is rejected (maybe passing a const rvalue should still succeed for consistency?)</li>
</ul>
<p>All of these declarations insert an extra trailing template parameter, in the same way that <code class="sourceCode cpp"><span class="kw">auto</span></code> function parameters do today. So <code class="sourceCode cpp">f<span class="op">(</span><span class="st">&quot;hello&quot;</span><span class="op">)</span></code> would fail (<code class="sourceCode cpp"><span class="st">&quot;hello&quot;</span></code> is not a <code class="sourceCode cpp">std<span class="op">::</span>string</code> or something derived from it), but <code class="sourceCode cpp">f<span class="op">&lt;</span>std<span class="op">::</span>string<span class="op">&gt;(</span><span class="st">&quot;hello&quot;</span><span class="op">)</span></code> would work (as the implicit next template parameter that denotes the type of <code class="sourceCode cpp">a</code>).</p>
<p>Of these two, my preference is for <strong>the latter</strong>: <code class="sourceCode cpp">forward T param</code>. It’s a new kind of deduction so having distinct syntax, the additionally makes clear the intended use of these parameters, is an advantage.</p>
<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 hanging-indent" role="doc-bibliography">
<div id="ref-P0798R8">
<p>[P0798R8] Sy Brand. 2021. Monadic operations for std::optional. <br />
<a href="https://wiki.edg.com/pub/Wg21virtual2021-10/StrawPolls/p0798r8.html">https://wiki.edg.com/pub/Wg21virtual2021-10/StrawPolls/p0798r8.html</a></p>
</div>
<div id="ref-P0847R7">
<p>[P0847R7] Barry Revzin, Gašper Ažman, Sy Brand, Ben Deane. 2021-07-14. Deducing this. <br />
<a href="https://wg21.link/p0847r7">https://wg21.link/p0847r7</a></p>
</div>
<div id="ref-P2481R0">
<p>[P2481R0] Barry Revzin. 2021-10-15. Forwarding reference to specific type/template. <br />
<a href="https://wg21.link/p2481r0">https://wg21.link/p2481r0</a></p>
</div>
<div id="ref-P2481R1">
<p>[P2481R1] Barry Revzin. 2022-07-15. Forwarding reference to specific type/template. <br />
<a href="https://wg21.link/p2481r1">https://wg21.link/p2481r1</a></p>
</div>
</div>
</div>
</div>
</body>
</html>
