<!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="2021-07-12" />
  <title>Deducing this</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">Deducing this</h1>

<table style="border:none;float:right">
  <tr>
    <td>Document #:</td>
    <td>P0847R7</td>
  </tr>
  <tr>
    <td>Date:</td>
    <td>2021-07-12</td>
  </tr>
  <tr>
    <td style="vertical-align:top">Project:</td>
    <td>Programming Language C++</td>
  </tr>
  <tr>
    <td style="vertical-align:top">Audience:</td>
    <td>
      EWG<br>
    </td>
  </tr>
  <tr>
    <td style="vertical-align:top">Reply-to:</td>
    <td>
      Gašper Ažman<br>&lt;<a href="mailto:gasper.azman@gmail.com" class="email">gasper.azman@gmail.com</a>&gt;<br>
      Sy Brand<br>&lt;<a href="mailto:sibrand@microsoft.com" class="email">sibrand@microsoft.com</a>&gt;<br>
      Ben Deane, ben at elbeno dot com<br>&lt;<a href="mailto:ben@elbeno.com" class="email">ben@elbeno.com</a>&gt;<br>
      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="#abstract"><span class="toc-section-number">1</span> Abstract<span></span></a></li>
<li><a href="#revision-history"><span class="toc-section-number">2</span> Revision History<span></span></a></li>
<li><a href="#motivation"><span class="toc-section-number">3</span> Motivation<span></span></a></li>
<li><a href="#proposal"><span class="toc-section-number">4</span> Proposal<span></span></a>
<ul>
<li><a href="#proposed-syntax"><span class="toc-section-number">4.1</span> Proposed Syntax<span></span></a></li>
<li><a href="#proposed-semantics"><span class="toc-section-number">4.2</span> Proposed semantics<span></span></a>
<ul>
<li><a href="#name-lookup-candidate-functions"><span class="toc-section-number">4.2.1</span> Name lookup: candidate functions<span></span></a></li>
<li><a href="#type-deduction"><span class="toc-section-number">4.2.2</span> Type deduction<span></span></a></li>
<li><a href="#by-value-this"><span class="toc-section-number">4.2.3</span> By value <code class="sourceCode cpp"><span class="kw">this</span></code><span></span></a></li>
<li><a href="#name-lookup-within-member-functions"><span class="toc-section-number">4.2.4</span> Name lookup: within member functions<span></span></a></li>
<li><a href="#the-shadowing-mitigation-private-inheritance-problem"><span class="toc-section-number">4.2.5</span> The Shadowing Mitigation / Private Inheritance Problem<span></span></a></li>
<li><a href="#writing-function-pointer-types"><span class="toc-section-number">4.2.6</span> Writing the function pointer types for such functions<span></span></a></li>
<li><a href="#pathological-cases"><span class="toc-section-number">4.2.7</span> Pathological cases<span></span></a></li>
<li><a href="#teachability-implications"><span class="toc-section-number">4.2.8</span> Teachability Implications<span></span></a></li>
<li><a href="#static-member-functions"><span class="toc-section-number">4.2.9</span> Can <code class="sourceCode cpp"><span class="kw">static</span></code> member functions have an explicit object type?<span></span></a></li>
<li><a href="#interplays-with-capturing-this"><span class="toc-section-number">4.2.10</span> Interplays with capturing <code class="sourceCode cpp"><span class="op">[</span><span class="kw">this</span><span class="op">]</span></code> and <code class="sourceCode cpp"><span class="op">[*</span><span class="kw">this</span><span class="op">]</span></code> in lambdas<span></span></a></li>
<li><a href="#parsing-issues"><span class="toc-section-number">4.2.11</span> Parsing issues<span></span></a></li>
<li><a href="#code-issues"><span class="toc-section-number">4.2.12</span> Code issues<span></span></a></li>
</ul></li>
<li><a href="#not-quite-static-not-quite-non-static"><span class="toc-section-number">4.3</span> Not quite static, not quite non-static<span></span></a>
<ul>
<li><a href="#implicit-this-access"><span class="toc-section-number">4.3.1</span> Implicit this access<span></span></a></li>
<li><a href="#explicit-object-parameter-and-virtual"><span class="toc-section-number">4.3.2</span> Explicit object parameter and virtual<span></span></a></li>
</ul></li>
</ul></li>
<li><a href="#real-world-examples"><span class="toc-section-number">5</span> Real-World Examples<span></span></a>
<ul>
<li><a href="#deduplicating-code"><span class="toc-section-number">5.1</span> Deduplicating Code<span></span></a></li>
<li><a href="#crtp"><span class="toc-section-number">5.2</span> CRTP, without the C, R, or even T<span></span></a>
<ul>
<li><a href="#builder-pattern"><span class="toc-section-number">5.2.1</span> Builder pattern<span></span></a></li>
</ul></li>
<li><a href="#recursive-lambdas"><span class="toc-section-number">5.3</span> Recursive Lambdas<span></span></a></li>
<li><a href="#by-value-member-functions"><span class="toc-section-number">5.4</span> By-value member functions<span></span></a>
<ul>
<li><a href="#move-into-parameter"><span class="toc-section-number">5.4.1</span> For move-into-parameter chaining<span></span></a></li>
<li><a href="#by-value-member-functions-for-performance"><span class="toc-section-number">5.4.2</span> For performance<span></span></a></li>
<li><a href="#for-lifetime-management-of-coroutines"><span class="toc-section-number">5.4.3</span> For lifetime management of coroutines<span></span></a></li>
</ul></li>
<li><a href="#sfinae-friendly-callables"><span class="toc-section-number">5.5</span> SFINAE-friendly callables<span></span></a></li>
</ul></li>
<li><a href="#faq"><span class="toc-section-number">6</span> Frequently Asked Questions<span></span></a>
<ul>
<li><a href="#faq-rec-lambda-impl"><span class="toc-section-number">6.1</span> On the implementability of recursive lambdas<span></span></a></li>
<li><a href="#faq-demand"><span class="toc-section-number">6.2</span> Would library implementers use this<span></span></a></li>
<li><a href="#faq-function-ptr-type"><span class="toc-section-number">6.3</span> Function Pointer Types<span></span></a></li>
<li><a href="#faq-computed-deduction"><span class="toc-section-number">6.4</span> Deducing to Base-Class Pointer<span></span></a></li>
<li><a href="#was-this-syntax-considered"><span class="toc-section-number">6.5</span> Was this syntax considered?<span></span></a></li>
</ul></li>
<li><a href="#reflection"><span class="toc-section-number">7</span> Reflection<span></span></a>
<ul>
<li><a href="#deduplicating-code-1"><span class="toc-section-number">7.1</span> Deduplicating Code<span></span></a></li>
<li><a href="#better-mixin-support"><span class="toc-section-number">7.2</span> Better mixin support<span></span></a></li>
<li><a href="#the-other-three"><span class="toc-section-number">7.3</span> The other three<span></span></a></li>
<li><a href="#reflection-vs-deducing-this"><span class="toc-section-number">7.4</span> Reflection vs deducing this<span></span></a></li>
</ul></li>
<li><a href="#implementation"><span class="toc-section-number">8</span> Implementation<span></span></a></li>
<li><a href="#wording"><span class="toc-section-number">9</span> Proposed Wording<span></span></a>
<ul>
<li><a href="#overview"><span class="toc-section-number">9.1</span> Overview<span></span></a></li>
<li><a href="#wording-1"><span class="toc-section-number">9.2</span> Wording<span></span></a>
<ul>
<li><a href="#wording-in-basic"><span class="toc-section-number">9.2.1</span> Wording in <span>6
 <span>[basic]</span></span><span></span></a></li>
<li><a href="#wording-in-expr"><span class="toc-section-number">9.2.2</span> Wording in <span>7
 <span>[expr]</span></span><span></span></a></li>
<li><a href="#dcl.dcl"><span class="toc-section-number">9.2.3</span> Wording in <span>9
 <span>[dcl.dcl]</span></span><span></span></a></li>
<li><a href="#wording-in-class"><span class="toc-section-number">9.2.4</span> Wording in <span>11
 <span>[class]</span></span><span></span></a></li>
<li><a href="#wording-in-over"><span class="toc-section-number">9.2.5</span> Wording in <span>12
 <span>[over]</span></span><span></span></a></li>
<li><a href="#wording-in-temp"><span class="toc-section-number">9.2.6</span> Wording in <span>13
 <span>[temp]</span></span><span></span></a></li>
</ul></li>
<li><a href="#feature-test-macro-tabcpp.predefined.ft"><span class="toc-section-number">9.3</span> Feature-test macro [tab:cpp.predefined.ft]<span></span></a></li>
</ul></li>
<li><a href="#acknowledgements"><span class="toc-section-number">10</span> Acknowledgements<span></span></a></li>
<li><a href="#bibliography"><span class="toc-section-number">11</span> References<span></span></a></li>
</ul>
</div>
<h1 data-number="1" style="border-bottom:1px solid #cccccc" id="abstract"><span class="header-section-number">1</span> Abstract<a href="#abstract" class="self-link"></a></h1>
<p>We propose a new mechanism for specifying or deducing the value category of the expression that a member-function is invoked on. In other words, a way to tell from within a member function whether the expression it’s invoked on is an lvalue or an rvalue; whether it is const or volatile; and the expression’s type.</p>
<h1 data-number="2" style="border-bottom:1px solid #cccccc" id="revision-history"><span class="header-section-number">2</span> Revision History<a href="#revision-history" class="self-link"></a></h1>
<p><strong><em>Changes since r6</em></strong></p>
<p>Wording changes after CWG telecon.</p>
<p><strong><em>Changes since r5</em></strong></p>
<p>Re-added section with the history of other syntaxes we considered (for posterity) and a discussion of reflection, explicit <code class="sourceCode cpp"><span class="kw">static</span></code>, <code class="sourceCode cpp"><span class="kw">virtual</span></code>, and coroutines. Rebased wording after Davis’ paper. Re-worded so that explicit object member functions are <em>non-static</em> member functions rather than static member functions.</p>
<p><strong><em>Changes since r4</em></strong></p>
<p>Wording and Implementation. Discussion about implicit vs explicit invocation and interaction with static functions.</p>
<p><strong><em>Changes since r3</em></strong></p>
<p>The feedback from Belfast in EWG was “This looks good, come back with wording and implementation”. This version adds wording, the implementation is in the works.</p>
<p><strong><em>Changes since r2</em></strong></p>
<p><span class="citation" data-cites="P0847R2">[<a href="#ref-P0847R2" role="doc-biblioref">P0847R2</a>]</span> was presented in Kona in Jaunary 2019 to EWGI, with generally enthusiastic support.</p>
<p>This version adds:</p>
<ul>
<li>An FAQ entry for <a href="#faq-demand">library implementor feedback</a></li>
<li>An FAQ entry for <a href="#faq-rec-lambda-impl">implementability</a></li>
<li>An FAQ entry for <a href="#faq-computed-deduction">computed deduction</a>, an orthogonal feature that EWGI asked for in Kona.</li>
</ul>
<p><strong><em>Changes since r1</em></strong></p>
<p><span class="citation" data-cites="P0847R1">[<a href="#ref-P0847R1" role="doc-biblioref">P0847R1</a>]</span> was presented in San Diego in November 2018 with a wide array of syntaxes and name lookup options. Discussion there revealed some potential issues with regards to lambdas that needed to be ironed out. This revision zeroes in on one specific syntax and name lookup semantic which solves all the use-cases.</p>
<p><strong><em>Changes since r0</em></strong></p>
<p><span class="citation" data-cites="P0847R0">[<a href="#ref-P0847R0" role="doc-biblioref">P0847R0</a>]</span> was presented in Rapperswil in June 2018 using a syntax adjusted from the one used in that paper, using <code class="sourceCode cpp"><span class="kw">this</span> Self<span class="op">&amp;&amp;</span> self</code> to indicate the explicit object parameter rather than the <code class="sourceCode cpp">Self<span class="op">&amp;&amp;</span> <span class="kw">this</span> self</code> that appeared in r0 of our paper.</p>
<p>EWG strongly encouraged us to look in two new directions:</p>
<ul>
<li>a different syntax, placing the object parameter’s type after the member function’s parameter declarations (where the <em>cv-ref</em> qualifiers are today)</li>
<li>a different name lookup scheme, which could prevent implicit/unqualified access from within new-style member functions that have an explicit self-type annotation, regardless of syntax.</li>
</ul>
<p>This revision carefully explores both of these directions, presents different syntaxes and lookup schemes, and discusses in depth multiple use cases and how each syntax can or cannot address them.</p>
<h1 data-number="3" style="border-bottom:1px solid #cccccc" id="motivation"><span class="header-section-number">3</span> Motivation<a href="#motivation" class="self-link"></a></h1>
<p>In C++03, member functions could have <em>cv</em>-qualifications, so it was possible to have scenarios where a particular class would want both a <code class="sourceCode cpp"><span class="kw">const</span></code> and non-<code class="sourceCode cpp"><span class="kw">const</span></code> overload of a particular member. (Note that it was also possible to want <code class="sourceCode cpp"><span class="kw">volatile</span></code> overloads, but those are less common and thus are not examined here.) In these cases, both overloads do the same thing — the only difference is in the types being accessed and used. This was handled by either duplicating the function while adjusting types and qualifications as necessary, or having one overload delegate to the other. An example of the latter can be found in Scott Meyers’s “Effective C++” <span class="citation" data-cites="Effective">[<a href="#ref-Effective" role="doc-biblioref">EffCpp</a>]</span>, Item 3:</p>
<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">class</span> TextBlock <span class="op">{</span></span>
<span id="cb1-2"><a href="#cb1-2"></a><span class="kw">public</span><span class="op">:</span></span>
<span id="cb1-3"><a href="#cb1-3"></a>  <span class="dt">char</span> <span class="kw">const</span><span class="op">&amp;</span> <span class="kw">operator</span><span class="op">[](</span><span class="dt">size_t</span> position<span class="op">)</span> <span class="kw">const</span> <span class="op">{</span></span>
<span id="cb1-4"><a href="#cb1-4"></a>    <span class="co">// ...</span></span>
<span id="cb1-5"><a href="#cb1-5"></a>    <span class="cf">return</span> text<span class="op">[</span>position<span class="op">]</span>;</span>
<span id="cb1-6"><a href="#cb1-6"></a>  <span class="op">}</span></span>
<span id="cb1-7"><a href="#cb1-7"></a></span>
<span id="cb1-8"><a href="#cb1-8"></a>  <span class="dt">char</span><span class="op">&amp;</span> <span class="kw">operator</span><span class="op">[](</span><span class="dt">size_t</span> position<span class="op">)</span> <span class="op">{</span></span>
<span id="cb1-9"><a href="#cb1-9"></a>    <span class="cf">return</span> <span class="kw">const_cast</span><span class="op">&lt;</span><span class="dt">char</span><span class="op">&amp;&gt;(</span></span>
<span id="cb1-10"><a href="#cb1-10"></a>      <span class="kw">static_cast</span><span class="op">&lt;</span>TextBlock <span class="kw">const</span><span class="op">&amp;&gt;(*</span><span class="kw">this</span><span class="op">)[</span>position<span class="op">]</span></span>
<span id="cb1-11"><a href="#cb1-11"></a>    <span class="op">)</span>;</span>
<span id="cb1-12"><a href="#cb1-12"></a>  <span class="op">}</span></span>
<span id="cb1-13"><a href="#cb1-13"></a>  <span class="co">// ...</span></span>
<span id="cb1-14"><a href="#cb1-14"></a><span class="op">}</span>;</span></code></pre></div>
<p>Arguably, neither duplication nor delegation via <code class="sourceCode cpp"><span class="kw">const_cast</span></code> are great solutions, but they work.</p>
<p>In C++11, member functions acquired a new axis to specialize on: ref-qualifiers. Now, instead of potentially needing two overloads of a single member function, we might need four: <code class="sourceCode cpp"><span class="op">&amp;</span></code>, <code class="sourceCode cpp"><span class="kw">const</span><span class="op">&amp;</span></code>, <code class="sourceCode cpp"><span class="op">&amp;&amp;</span></code>, or <code class="sourceCode cpp"><span class="kw">const</span><span class="op">&amp;&amp;</span></code>. We have three approaches to deal with this:</p>
<ul>
<li>We implement the same member four times;</li>
<li>We have three overloads delegate to the fourth; or</li>
<li>We have all four overloads delegate to a helper in the form of a private static member function.</li>
</ul>
<p>One example of the latter might be the overload set for <code class="sourceCode cpp">optional<span class="op">&lt;</span>T<span class="op">&gt;::</span>value<span class="op">()</span></code>, implemented as:</p>
<table style="width:100%">
<tr>
<th style="width:33%">
Quadruplication
</th>
<th style="width:33%">
Delegation to 4th
</th>
<th style="width:33%">
Delegation to helper
</th>
</tr>
<tr>
<td>
<div class="sourceCode" id="cb2"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb2-1"><a href="#cb2-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="cb2-2"><a href="#cb2-2"></a><span class="kw">class</span> optional <span class="op">{</span></span>
<span id="cb2-3"><a href="#cb2-3"></a>  <span class="co">// ...</span></span>
<span id="cb2-4"><a href="#cb2-4"></a>  <span class="kw">constexpr</span> T<span class="op">&amp;</span> value<span class="op">()</span> <span class="op">&amp;</span> <span class="op">{</span></span>
<span id="cb2-5"><a href="#cb2-5"></a>    <span class="cf">if</span> <span class="op">(</span>has_value<span class="op">())</span> <span class="op">{</span></span>
<span id="cb2-6"><a href="#cb2-6"></a>      <span class="cf">return</span> <span class="kw">this</span><span class="op">-&gt;</span>m_value;</span>
<span id="cb2-7"><a href="#cb2-7"></a>    <span class="op">}</span></span>
<span id="cb2-8"><a href="#cb2-8"></a>    <span class="cf">throw</span> bad_optional_access<span class="op">()</span>;</span>
<span id="cb2-9"><a href="#cb2-9"></a>  <span class="op">}</span></span>
<span id="cb2-10"><a href="#cb2-10"></a></span>
<span id="cb2-11"><a href="#cb2-11"></a>  <span class="kw">constexpr</span> T <span class="kw">const</span><span class="op">&amp;</span> value<span class="op">()</span> <span class="kw">const</span><span class="op">&amp;</span> <span class="op">{</span></span>
<span id="cb2-12"><a href="#cb2-12"></a>    <span class="cf">if</span> <span class="op">(</span>has_value<span class="op">())</span> <span class="op">{</span></span>
<span id="cb2-13"><a href="#cb2-13"></a>      <span class="cf">return</span> <span class="kw">this</span><span class="op">-&gt;</span>m_value;</span>
<span id="cb2-14"><a href="#cb2-14"></a>    <span class="op">}</span></span>
<span id="cb2-15"><a href="#cb2-15"></a>    <span class="cf">throw</span> bad_optional_access<span class="op">()</span>;</span>
<span id="cb2-16"><a href="#cb2-16"></a>  <span class="op">}</span></span>
<span id="cb2-17"><a href="#cb2-17"></a></span>
<span id="cb2-18"><a href="#cb2-18"></a>  <span class="kw">constexpr</span> T<span class="op">&amp;&amp;</span> value<span class="op">()</span> <span class="op">&amp;&amp;</span> <span class="op">{</span></span>
<span id="cb2-19"><a href="#cb2-19"></a>    <span class="cf">if</span> <span class="op">(</span>has_value<span class="op">())</span> <span class="op">{</span></span>
<span id="cb2-20"><a href="#cb2-20"></a>      <span class="cf">return</span> move<span class="op">(</span><span class="kw">this</span><span class="op">-&gt;</span>m_value<span class="op">)</span>;</span>
<span id="cb2-21"><a href="#cb2-21"></a>    <span class="op">}</span></span>
<span id="cb2-22"><a href="#cb2-22"></a>    <span class="cf">throw</span> bad_optional_access<span class="op">()</span>;</span>
<span id="cb2-23"><a href="#cb2-23"></a>  <span class="op">}</span></span>
<span id="cb2-24"><a href="#cb2-24"></a></span>
<span id="cb2-25"><a href="#cb2-25"></a>  <span class="kw">constexpr</span> T <span class="kw">const</span><span class="op">&amp;&amp;</span></span>
<span id="cb2-26"><a href="#cb2-26"></a>  value<span class="op">()</span> <span class="kw">const</span><span class="op">&amp;&amp;</span> <span class="op">{</span></span>
<span id="cb2-27"><a href="#cb2-27"></a>    <span class="cf">if</span> <span class="op">(</span>has_value<span class="op">())</span> <span class="op">{</span></span>
<span id="cb2-28"><a href="#cb2-28"></a>      <span class="cf">return</span> move<span class="op">(</span><span class="kw">this</span><span class="op">-&gt;</span>m_value<span class="op">)</span>;</span>
<span id="cb2-29"><a href="#cb2-29"></a>    <span class="op">}</span></span>
<span id="cb2-30"><a href="#cb2-30"></a>    <span class="cf">throw</span> bad_optional_access<span class="op">()</span>;</span>
<span id="cb2-31"><a href="#cb2-31"></a>  <span class="op">}</span></span>
<span id="cb2-32"><a href="#cb2-32"></a>  <span class="co">// ...</span></span>
<span id="cb2-33"><a href="#cb2-33"></a><span class="op">}</span>;</span></code></pre></div>
</td>
<td>
<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> T<span class="op">&gt;</span></span>
<span id="cb3-2"><a href="#cb3-2"></a><span class="kw">class</span> optional <span class="op">{</span></span>
<span id="cb3-3"><a href="#cb3-3"></a>  <span class="co">// ...</span></span>
<span id="cb3-4"><a href="#cb3-4"></a>  <span class="kw">constexpr</span> T<span class="op">&amp;</span> value<span class="op">()</span> <span class="op">&amp;</span> <span class="op">{</span></span>
<span id="cb3-5"><a href="#cb3-5"></a>    <span class="cf">return</span> <span class="kw">const_cast</span><span class="op">&lt;</span>T<span class="op">&amp;&gt;(</span></span>
<span id="cb3-6"><a href="#cb3-6"></a>      <span class="kw">static_cast</span><span class="op">&lt;</span>optional <span class="kw">const</span><span class="op">&amp;&gt;(</span></span>
<span id="cb3-7"><a href="#cb3-7"></a>        <span class="op">*</span><span class="kw">this</span><span class="op">).</span>value<span class="op">())</span>;</span>
<span id="cb3-8"><a href="#cb3-8"></a>  <span class="op">}</span></span>
<span id="cb3-9"><a href="#cb3-9"></a></span>
<span id="cb3-10"><a href="#cb3-10"></a>  <span class="kw">constexpr</span> T <span class="kw">const</span><span class="op">&amp;</span> value<span class="op">()</span> <span class="kw">const</span><span class="op">&amp;</span> <span class="op">{</span></span>
<span id="cb3-11"><a href="#cb3-11"></a>    <span class="cf">if</span> <span class="op">(</span>has_value<span class="op">())</span> <span class="op">{</span></span>
<span id="cb3-12"><a href="#cb3-12"></a>      <span class="cf">return</span> <span class="kw">this</span><span class="op">-&gt;</span>m_value;</span>
<span id="cb3-13"><a href="#cb3-13"></a>    <span class="op">}</span></span>
<span id="cb3-14"><a href="#cb3-14"></a>    <span class="cf">throw</span> bad_optional_access<span class="op">()</span>;</span>
<span id="cb3-15"><a href="#cb3-15"></a>  <span class="op">}</span></span>
<span id="cb3-16"><a href="#cb3-16"></a></span>
<span id="cb3-17"><a href="#cb3-17"></a>  <span class="kw">constexpr</span> T<span class="op">&amp;&amp;</span> value<span class="op">()</span> <span class="op">&amp;&amp;</span> <span class="op">{</span></span>
<span id="cb3-18"><a href="#cb3-18"></a>    <span class="cf">return</span> <span class="kw">const_cast</span><span class="op">&lt;</span>T<span class="op">&amp;&amp;&gt;(</span></span>
<span id="cb3-19"><a href="#cb3-19"></a>      <span class="kw">static_cast</span><span class="op">&lt;</span>optional <span class="kw">const</span><span class="op">&amp;&gt;(</span></span>
<span id="cb3-20"><a href="#cb3-20"></a>        <span class="op">*</span><span class="kw">this</span><span class="op">).</span>value<span class="op">())</span>;</span>
<span id="cb3-21"><a href="#cb3-21"></a>  <span class="op">}</span></span>
<span id="cb3-22"><a href="#cb3-22"></a></span>
<span id="cb3-23"><a href="#cb3-23"></a>  <span class="kw">constexpr</span> T <span class="kw">const</span><span class="op">&amp;&amp;</span></span>
<span id="cb3-24"><a href="#cb3-24"></a>  value<span class="op">()</span> <span class="kw">const</span><span class="op">&amp;&amp;</span> <span class="op">{</span></span>
<span id="cb3-25"><a href="#cb3-25"></a>    <span class="cf">return</span> <span class="kw">static_cast</span><span class="op">&lt;</span>T <span class="kw">const</span><span class="op">&amp;&amp;&gt;(</span></span>
<span id="cb3-26"><a href="#cb3-26"></a>      value<span class="op">())</span>;</span>
<span id="cb3-27"><a href="#cb3-27"></a>  <span class="op">}</span></span>
<span id="cb3-28"><a href="#cb3-28"></a>  <span class="co">// ...</span></span>
<span id="cb3-29"><a href="#cb3-29"></a><span class="op">}</span>;</span></code></pre></div>
</td>
<td>
<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="kw">typename</span> T<span class="op">&gt;</span></span>
<span id="cb4-2"><a href="#cb4-2"></a><span class="kw">class</span> optional <span class="op">{</span></span>
<span id="cb4-3"><a href="#cb4-3"></a>  <span class="co">// ...</span></span>
<span id="cb4-4"><a href="#cb4-4"></a>  <span class="kw">constexpr</span> T<span class="op">&amp;</span> value<span class="op">()</span> <span class="op">&amp;</span> <span class="op">{</span></span>
<span id="cb4-5"><a href="#cb4-5"></a>    <span class="cf">return</span> value_impl<span class="op">(*</span><span class="kw">this</span><span class="op">)</span>;</span>
<span id="cb4-6"><a href="#cb4-6"></a>  <span class="op">}</span></span>
<span id="cb4-7"><a href="#cb4-7"></a></span>
<span id="cb4-8"><a href="#cb4-8"></a>  <span class="kw">constexpr</span> T <span class="kw">const</span><span class="op">&amp;</span> value<span class="op">()</span> <span class="kw">const</span><span class="op">&amp;</span> <span class="op">{</span></span>
<span id="cb4-9"><a href="#cb4-9"></a>    <span class="cf">return</span> value_impl<span class="op">(*</span><span class="kw">this</span><span class="op">)</span>;</span>
<span id="cb4-10"><a href="#cb4-10"></a>  <span class="op">}</span></span>
<span id="cb4-11"><a href="#cb4-11"></a></span>
<span id="cb4-12"><a href="#cb4-12"></a>  <span class="kw">constexpr</span> T<span class="op">&amp;&amp;</span> value<span class="op">()</span> <span class="op">&amp;&amp;</span> <span class="op">{</span></span>
<span id="cb4-13"><a href="#cb4-13"></a>    <span class="cf">return</span> value_impl<span class="op">(</span>move<span class="op">(*</span><span class="kw">this</span><span class="op">))</span>;</span>
<span id="cb4-14"><a href="#cb4-14"></a>  <span class="op">}</span></span>
<span id="cb4-15"><a href="#cb4-15"></a></span>
<span id="cb4-16"><a href="#cb4-16"></a>  <span class="kw">constexpr</span> T <span class="kw">const</span><span class="op">&amp;&amp;</span></span>
<span id="cb4-17"><a href="#cb4-17"></a>  value<span class="op">()</span> <span class="kw">const</span><span class="op">&amp;&amp;</span> <span class="op">{</span></span>
<span id="cb4-18"><a href="#cb4-18"></a>    <span class="cf">return</span> value_impl<span class="op">(</span>move<span class="op">(*</span><span class="kw">this</span><span class="op">))</span>;</span>
<span id="cb4-19"><a href="#cb4-19"></a>  <span class="op">}</span></span>
<span id="cb4-20"><a href="#cb4-20"></a></span>
<span id="cb4-21"><a href="#cb4-21"></a><span class="kw">private</span><span class="op">:</span></span>
<span id="cb4-22"><a href="#cb4-22"></a>  <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> Opt<span class="op">&gt;</span></span>
<span id="cb4-23"><a href="#cb4-23"></a>  <span class="kw">static</span> <span class="kw">decltype</span><span class="op">(</span><span class="kw">auto</span><span class="op">)</span></span>
<span id="cb4-24"><a href="#cb4-24"></a>  value_impl<span class="op">(</span>Opt<span class="op">&amp;&amp;</span> opt<span class="op">)</span> <span class="op">{</span></span>
<span id="cb4-25"><a href="#cb4-25"></a>    <span class="cf">if</span> <span class="op">(!</span>opt<span class="op">.</span>has_value<span class="op">())</span> <span class="op">{</span></span>
<span id="cb4-26"><a href="#cb4-26"></a>      <span class="cf">throw</span> bad_optional_access<span class="op">()</span>;</span>
<span id="cb4-27"><a href="#cb4-27"></a>    <span class="op">}</span></span>
<span id="cb4-28"><a href="#cb4-28"></a>    <span class="cf">return</span> forward<span class="op">&lt;</span>Opt<span class="op">&gt;(</span>opt<span class="op">).</span>m_value;</span>
<span id="cb4-29"><a href="#cb4-29"></a>  <span class="op">}</span></span>
<span id="cb4-30"><a href="#cb4-30"></a>  <span class="co">// ...</span></span>
<span id="cb4-31"><a href="#cb4-31"></a><span class="op">}</span>;</span></code></pre></div>
</td>
</tr>
</table>
<p>This is far from a complicated function, but essentially repeating the same code four times — or using artificial delegation to avoid doing so — begs a rewrite. Unfortunately, it’s impossible to improve; we <em>must</em> implement it this way. It seems we should be able to abstract away the qualifiers as we can for non-member functions, where we simply don’t have this problem:</p>
<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">class</span> optional <span class="op">{</span></span>
<span id="cb5-3"><a href="#cb5-3"></a>    <span class="co">// ...</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> Opt<span class="op">&gt;</span></span>
<span id="cb5-5"><a href="#cb5-5"></a>    <span class="kw">friend</span> <span class="kw">decltype</span><span class="op">(</span><span class="kw">auto</span><span class="op">)</span> value<span class="op">(</span>Opt<span class="op">&amp;&amp;</span> o<span class="op">)</span> <span class="op">{</span></span>
<span id="cb5-6"><a href="#cb5-6"></a>        <span class="cf">if</span> <span class="op">(</span>o<span class="op">.</span>has_value<span class="op">())</span> <span class="op">{</span></span>
<span id="cb5-7"><a href="#cb5-7"></a>            <span class="cf">return</span> forward<span class="op">&lt;</span>Opt<span class="op">&gt;(</span>o<span class="op">).</span>m_value;</span>
<span id="cb5-8"><a href="#cb5-8"></a>        <span class="op">}</span></span>
<span id="cb5-9"><a href="#cb5-9"></a>        <span class="cf">throw</span> bad_optional_access<span class="op">()</span>;</span>
<span id="cb5-10"><a href="#cb5-10"></a>    <span class="op">}</span></span>
<span id="cb5-11"><a href="#cb5-11"></a>    <span class="co">// ...</span></span>
<span id="cb5-12"><a href="#cb5-12"></a><span class="op">}</span>;</span></code></pre></div>
<p>All four cases are now handled with just one function… except it’s a non-member function, not a member function. Different semantics, different syntax, doesn’t help.</p>
<p>There are many cases where we need two or four overloads of the same member function for different <code class="sourceCode cpp"><span class="kw">const</span></code>- or ref-qualifiers. More than that, there are likely additional cases where a class should have four overloads of a particular member function but, due to developer laziness, doesn’t. We think that there are enough such cases to merit a better solution than simply “write it, write it again, then write it two more times.”</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 a new way of declaring non-static member functions that will allow for deducing the type and value category of the class instance parameter while still being invocable with regular member function syntax. This is a strict extension to the language.</p>
<p>We believe that the ability to write <em>cv-ref qualifier</em>-aware member function templates without duplication will improve code maintainability, decrease the likelihood of bugs, and make fast, correct code easier to write.</p>
<p>The proposal is sufficiently general and orthogonal to allow for several new exciting features and design patterns for C++:</p>
<ul>
<li><a href="#recursive-lambdas">recursive lambdas</a></li>
<li>a new approach to <a href="#crtp">mixins</a>, a CRTP without the CRT</li>
<li><a href="#move-into-parameter">move-or-copy-into-parameter support for member functions</a></li>
<li>efficiency by avoiding double indirection with <a href="#by-value-member-functions-for-performance">invocation</a></li>
<li>perfect, sfinae-friendly <a href="#sfinae-friendly-callables">call wrappers</a></li>
</ul>
<p>These are explored in detail in the <a href="#real-world-examples">examples</a> section.</p>
<p>This proposal assumes the existence of two library additions, though it does not propose them:</p>
<ul>
<li><code class="sourceCode cpp">like_t</code>, a metafunction that applies the <em>cv</em>- and <em>ref</em>-qualifiers of the first type onto the second (e.g. <code class="sourceCode cpp">like_t<span class="op">&lt;</span><span class="dt">int</span><span class="op">&amp;</span>, <span class="dt">double</span><span class="op">&gt;</span></code> is <code class="sourceCode cpp"><span class="dt">double</span><span class="op">&amp;</span></code>, <code class="sourceCode cpp">like_t<span class="op">&lt;</span>X <span class="kw">const</span><span class="op">&amp;&amp;</span>, Y<span class="op">&gt;</span></code> is <code class="sourceCode cpp">Y <span class="kw">const</span><span class="op">&amp;&amp;</span></code>, etc.)</li>
<li><code class="sourceCode cpp">forward_like</code>, a version of <code class="sourceCode cpp">forward</code> that is intended to forward a variable not based on its own type but instead based on some other type. <code class="sourceCode cpp">forward_like<span class="op">&lt;</span>T<span class="op">&gt;(</span>u<span class="op">)</span></code> is short-hand for <code class="sourceCode cpp">forward<span class="op">&lt;</span>like_t<span class="op">&lt;</span>T,<span class="kw">decltype</span><span class="op">(</span>u<span class="op">)&gt;&gt;(</span>u<span class="op">)</span></code>.</li>
</ul>
<h2 data-number="4.1" id="proposed-syntax"><span class="header-section-number">4.1</span> Proposed Syntax<a href="#proposed-syntax" class="self-link"></a></h2>
<p>The proposed syntax in this paper is to use an explicit <code class="sourceCode cpp"><span class="kw">this</span></code>-annotated parameter.</p>
<p>A non-static member function can be declared to take as its first parameter an <em>explicit object parameter</em>, denoted with the prefixed keyword <code class="sourceCode cpp"><span class="kw">this</span></code>. Once we elevate the object parameter to a proper function parameter, it can be deduced following normal function template deduction rules:</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb6-1"><a href="#cb6-1"></a><span class="kw">struct</span> X <span class="op">{</span></span>
<span id="cb6-2"><a href="#cb6-2"></a>    <span class="dt">void</span> foo<span class="op">(</span><span class="kw">this</span> X <span class="kw">const</span><span class="op">&amp;</span> self, <span class="dt">int</span> i<span class="op">)</span>;</span>
<span id="cb6-3"><a href="#cb6-3"></a></span>
<span id="cb6-4"><a href="#cb6-4"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> Self<span class="op">&gt;</span></span>
<span id="cb6-5"><a href="#cb6-5"></a>    <span class="dt">void</span> bar<span class="op">(</span><span class="kw">this</span> Self<span class="op">&amp;&amp;</span> self<span class="op">)</span>;</span>
<span id="cb6-6"><a href="#cb6-6"></a><span class="op">}</span>;</span>
<span id="cb6-7"><a href="#cb6-7"></a></span>
<span id="cb6-8"><a href="#cb6-8"></a><span class="kw">struct</span> D <span class="op">:</span> X <span class="op">{</span> <span class="op">}</span>;</span>
<span id="cb6-9"><a href="#cb6-9"></a></span>
<span id="cb6-10"><a href="#cb6-10"></a><span class="dt">void</span> ex<span class="op">(</span>X<span class="op">&amp;</span> x, D <span class="kw">const</span><span class="op">&amp;</span> d<span class="op">)</span> <span class="op">{</span></span>
<span id="cb6-11"><a href="#cb6-11"></a>    x<span class="op">.</span>foo<span class="op">(</span><span class="dv">42</span><span class="op">)</span>;      <span class="co">// &#39;self&#39; is bound to &#39;x&#39;, &#39;i&#39; is 42</span></span>
<span id="cb6-12"><a href="#cb6-12"></a>    x<span class="op">.</span>bar<span class="op">()</span>;        <span class="co">// deduces Self as X&amp;, calls X::bar&lt;X&amp;&gt;</span></span>
<span id="cb6-13"><a href="#cb6-13"></a>    move<span class="op">(</span>x<span class="op">).</span>bar<span class="op">()</span>;  <span class="co">// deduces Self as X, calls X::bar&lt;X&gt;</span></span>
<span id="cb6-14"><a href="#cb6-14"></a></span>
<span id="cb6-15"><a href="#cb6-15"></a>    d<span class="op">.</span>foo<span class="op">(</span><span class="dv">17</span><span class="op">)</span>;      <span class="co">// &#39;self&#39; is bound to &#39;d&#39;</span></span>
<span id="cb6-16"><a href="#cb6-16"></a>    d<span class="op">.</span>bar<span class="op">()</span>;        <span class="co">// deduces Self as D const&amp;, calls X::bar&lt;D const&amp;&gt;</span></span>
<span id="cb6-17"><a href="#cb6-17"></a><span class="op">}</span></span></code></pre></div>
<p>Member functions with an explicit object parameter cannot be <code class="sourceCode cpp"><span class="kw">static</span></code> or <code class="sourceCode cpp"><span class="kw">virtual</span></code> and they cannot have <em>cv</em>- or <em>ref</em>-qualifiers. We will discuss the restriction on <code class="sourceCode cpp"><span class="kw">static</span></code> and <code class="sourceCode cpp"><span class="kw">virtual</span></code> in followup sections.</p>
<p>A call to a member function will interpret the object argument as the first (<code class="sourceCode cpp"><span class="kw">this</span></code>-annotated) parameter to it; the first argument in the parenthesized expression list is then interpreted as the second parameter, and so forth.</p>
<p>Following normal deduction rules, the template parameter corresponding to the explicit object parameter can deduce to a type derived from the class in which the member function is declared, as in the example above for <code class="sourceCode cpp">d<span class="op">.</span>bar<span class="op">()</span></code>).</p>
<p>We can use this syntax to implement <code class="sourceCode cpp">optional<span class="op">::</span>value<span class="op">()</span></code> and <code class="sourceCode cpp">optional<span class="op">::</span><span class="kw">operator</span><span class="op">-&gt;()</span></code> in just two functions instead of the current six:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb7-1"><a href="#cb7-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span></span>
<span id="cb7-2"><a href="#cb7-2"></a><span class="kw">struct</span> optional <span class="op">{</span></span>
<span id="cb7-3"><a href="#cb7-3"></a>  <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> Self<span class="op">&gt;</span></span>
<span id="cb7-4"><a href="#cb7-4"></a>  <span class="kw">constexpr</span> <span class="kw">auto</span><span class="op">&amp;&amp;</span> value<span class="op">(</span><span class="kw">this</span> Self<span class="op">&amp;&amp;</span> self<span class="op">)</span> <span class="op">{</span></span>
<span id="cb7-5"><a href="#cb7-5"></a>    <span class="cf">if</span> <span class="op">(!</span>self<span class="op">.</span>has_value<span class="op">())</span> <span class="op">{</span></span>
<span id="cb7-6"><a href="#cb7-6"></a>      <span class="cf">throw</span> bad_optional_access<span class="op">()</span>;</span>
<span id="cb7-7"><a href="#cb7-7"></a>    <span class="op">}</span></span>
<span id="cb7-8"><a href="#cb7-8"></a></span>
<span id="cb7-9"><a href="#cb7-9"></a>    <span class="cf">return</span> forward<span class="op">&lt;</span>Self<span class="op">&gt;(</span>self<span class="op">).</span>m_value;</span>
<span id="cb7-10"><a href="#cb7-10"></a>  <span class="op">}</span></span>
<span id="cb7-11"><a href="#cb7-11"></a></span>
<span id="cb7-12"><a href="#cb7-12"></a>  <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> Self<span class="op">&gt;</span></span>
<span id="cb7-13"><a href="#cb7-13"></a>  <span class="kw">constexpr</span> <span class="kw">auto</span> <span class="kw">operator</span><span class="op">-&gt;(</span><span class="kw">this</span> Self<span class="op">&amp;&amp;</span> self<span class="op">)</span> <span class="op">{</span></span>
<span id="cb7-14"><a href="#cb7-14"></a>    <span class="cf">return</span> addressof<span class="op">(</span>self<span class="op">.</span>m_value<span class="op">)</span>;</span>
<span id="cb7-15"><a href="#cb7-15"></a>  <span class="op">}</span></span>
<span id="cb7-16"><a href="#cb7-16"></a><span class="op">}</span>;</span></code></pre></div>
<p>This syntax can be used in lambdas as well, with the <code class="sourceCode cpp"><span class="kw">this</span></code>-annotated parameter exposing a way to refer to the lambda itself in its body:</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb8-1"><a href="#cb8-1"></a>vector captured <span class="op">=</span> <span class="op">{</span><span class="dv">1</span>, <span class="dv">2</span>, <span class="dv">3</span>, <span class="dv">4</span><span class="op">}</span>;</span>
<span id="cb8-2"><a href="#cb8-2"></a><span class="op">[</span>captured<span class="op">](</span><span class="kw">this</span> <span class="kw">auto</span><span class="op">&amp;&amp;</span> self<span class="op">)</span> <span class="op">-&gt;</span> <span class="kw">decltype</span><span class="op">(</span><span class="kw">auto</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb8-3"><a href="#cb8-3"></a>  <span class="cf">return</span> forward_like<span class="op">&lt;</span><span class="kw">decltype</span><span class="op">(</span>self<span class="op">)&gt;(</span>captured<span class="op">)</span>;</span>
<span id="cb8-4"><a href="#cb8-4"></a><span class="op">}</span></span>
<span id="cb8-5"><a href="#cb8-5"></a></span>
<span id="cb8-6"><a href="#cb8-6"></a><span class="op">[</span>captured<span class="op">]&lt;</span><span class="kw">class</span> Self<span class="op">&gt;(</span><span class="kw">this</span> Self<span class="op">&amp;&amp;</span> self<span class="op">)</span> <span class="op">-&gt;</span> <span class="kw">decltype</span><span class="op">(</span><span class="kw">auto</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb8-7"><a href="#cb8-7"></a>  <span class="cf">return</span> forward_like<span class="op">&lt;</span>Self<span class="op">&gt;(</span>captured<span class="op">)</span>;</span>
<span id="cb8-8"><a href="#cb8-8"></a><span class="op">}</span></span></code></pre></div>
<p>The lambdas can either move or copy from the capture, depending on whether the lambda is an lvalue or an rvalue.</p>
<h2 data-number="4.2" id="proposed-semantics"><span class="header-section-number">4.2</span> Proposed semantics<a href="#proposed-semantics" class="self-link"></a></h2>
<p>What follows is a description of how deducing <code class="sourceCode cpp"><span class="kw">this</span></code> affects all important language constructs — name lookup, type deduction, overload resolution, and so forth.</p>
<h3 data-number="4.2.1" id="name-lookup-candidate-functions"><span class="header-section-number">4.2.1</span> Name lookup: candidate functions<a href="#name-lookup-candidate-functions" class="self-link"></a></h3>
<p><strong>In C++17</strong>, name lookup includes both static and non-static member functions found by regular class lookup when invoking a named function or an operator, including the call operator, on an object of class type. Non-static member functions are treated as if there were an implicit object parameter whose type is an lvalue or rvalue reference to <em>cv</em> <code class="sourceCode cpp">X</code> (where the reference and <em>cv</em> qualifiers are determined based on the function’s own qualifiers) which binds to the object on which the function was invoked.</p>
<p>For non-static member functions using an explicit object parameter, lookup will work the same way as other member functions in C++17, with one exception: rather than implicitly determining the type of the object parameter based on the <em>cv</em>- and <em>ref</em>-qualifiers of the member function, these are now explicitly determined by the provided type of the explicit object parameter. The following examples illustrate this concept.</p>
<table style="width:100%">
<tr>
<th style="width:50%">
C++17
</th>
<th style="width:50%">
Proposed
</th>
</tr>
<tr>
<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">struct</span> X <span class="op">{</span></span>
<span id="cb9-2"><a href="#cb9-2"></a>  <span class="co">// implicit object has type X&amp;</span></span>
<span id="cb9-3"><a href="#cb9-3"></a>  <span class="dt">void</span> foo<span class="op">()</span> <span class="op">&amp;</span>;</span>
<span id="cb9-4"><a href="#cb9-4"></a></span>
<span id="cb9-5"><a href="#cb9-5"></a>  <span class="co">// implicit object has type X const&amp;</span></span>
<span id="cb9-6"><a href="#cb9-6"></a>  <span class="dt">void</span> foo<span class="op">()</span> <span class="kw">const</span><span class="op">&amp;</span>;</span>
<span id="cb9-7"><a href="#cb9-7"></a></span>
<span id="cb9-8"><a href="#cb9-8"></a>  <span class="co">// implicit object has type X&amp;&amp;</span></span>
<span id="cb9-9"><a href="#cb9-9"></a>  <span class="dt">void</span> bar<span class="op">()</span> <span class="op">&amp;&amp;</span>;</span>
<span id="cb9-10"><a href="#cb9-10"></a><span class="op">}</span>;</span></code></pre></div>
</td>
<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">struct</span> X <span class="op">{</span></span>
<span id="cb10-2"><a href="#cb10-2"></a>  <span class="co">// explicit object has type X&amp;</span></span>
<span id="cb10-3"><a href="#cb10-3"></a>  <span class="dt">void</span> foo<span class="op">(</span><span class="kw">this</span> X<span class="op">&amp;)</span>;</span>
<span id="cb10-4"><a href="#cb10-4"></a></span>
<span id="cb10-5"><a href="#cb10-5"></a>  <span class="co">// explicit object has type X const&amp;</span></span>
<span id="cb10-6"><a href="#cb10-6"></a>  <span class="dt">void</span> foo<span class="op">(</span><span class="kw">this</span> X <span class="kw">const</span><span class="op">&amp;)</span>;</span>
<span id="cb10-7"><a href="#cb10-7"></a></span>
<span id="cb10-8"><a href="#cb10-8"></a>  <span class="co">// explicit object has type X&amp;&amp;</span></span>
<span id="cb10-9"><a href="#cb10-9"></a>  <span class="dt">void</span> bar<span class="op">(</span><span class="kw">this</span> X<span class="op">&amp;&amp;)</span>;</span>
<span id="cb10-10"><a href="#cb10-10"></a><span class="op">}</span>;</span></code></pre></div>
</td>
</tr>
</table>
<p>Name lookup on an expression like <code class="sourceCode cpp">obj<span class="op">.</span>foo<span class="op">()</span></code> in C++17 would find both overloads of <code class="sourceCode cpp">foo</code> in the first column, with the non-const overload discarded should <code class="sourceCode cpp">obj</code> be const.</p>
<p>With the proposed syntax, <code class="sourceCode cpp">obj<span class="op">.</span>foo<span class="op">()</span></code> would continue to find both overloads of <code class="sourceCode cpp">foo</code>, with identical behaviour to C++17.</p>
<p>The only change in how we look up candidate functions is in the case of an explicit object parameter, where the argument list is shifted by one. The first listed parameter is bound to the object argument, and the second listed parameter corresponds to the first argument of the call expression.</p>
<p>This paper does not propose any changes to overload <em>resolution</em> but merely suggests extending the candidate set to include non-static member functions and member function templates written in a new syntax. Therefore, given a call to <code class="sourceCode cpp">x<span class="op">.</span>foo<span class="op">()</span></code>, overload resolution would still select the first <code class="sourceCode cpp">foo<span class="op">()</span></code> overload if <code class="sourceCode cpp">x</code> is not <code class="sourceCode cpp"><span class="kw">const</span></code> and the second if it is.</p>
<p>The behaviors of the two columns are exactly equivalent as proposed.</p>
<p>The only change as far as candidates are concerned is that the proposal allows for deduction of the object parameter, which is new for the language.</p>
<p>Since in some cases there are multiple ways to declare the same function, it would be ill-formed to declare two functions with the same parameters and the same qualifiers for the object parameter. This is:</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb11-1"><a href="#cb11-1"></a><span class="kw">struct</span> X <span class="op">{</span></span>
<span id="cb11-2"><a href="#cb11-2"></a>    <span class="dt">void</span> bar<span class="op">()</span> <span class="op">&amp;&amp;</span>;</span>
<span id="cb11-3"><a href="#cb11-3"></a>    <span class="dt">void</span> bar<span class="op">(</span><span class="kw">this</span> X<span class="op">&amp;&amp;)</span>; <span class="co">// error: same this parameter type</span></span>
<span id="cb11-4"><a href="#cb11-4"></a>    </span>
<span id="cb11-5"><a href="#cb11-5"></a>    <span class="kw">static</span> <span class="dt">void</span> f<span class="op">()</span>;</span>
<span id="cb11-6"><a href="#cb11-6"></a>    <span class="dt">void</span> f<span class="op">(</span><span class="kw">this</span> X <span class="kw">const</span><span class="op">&amp;)</span>; <span class="co">// error: two functions taking no parameters</span></span>
<span id="cb11-7"><a href="#cb11-7"></a><span class="op">}</span>;</span></code></pre></div>
<p>But as long as any of the qualifiers are different, it is fine:</p>
<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">struct</span> Y <span class="op">{</span></span>
<span id="cb12-2"><a href="#cb12-2"></a>    <span class="dt">void</span> bar<span class="op">()</span> <span class="op">&amp;</span>;</span>
<span id="cb12-3"><a href="#cb12-3"></a>    <span class="dt">void</span> bar<span class="op">()</span> <span class="kw">const</span><span class="op">&amp;</span>;</span>
<span id="cb12-4"><a href="#cb12-4"></a>    <span class="dt">void</span> bar<span class="op">(</span><span class="kw">this</span> Y<span class="op">&amp;&amp;)</span>;</span>
<span id="cb12-5"><a href="#cb12-5"></a><span class="op">}</span>;</span></code></pre></div>
<p>The rule in question is <span>6.4.1
 <a href="https://wg21.link/basic.scope.scope">[basic.scope.scope]</a></span>/3, and is extended in the wording below.</p>
<h3 data-number="4.2.2" id="type-deduction"><span class="header-section-number">4.2.2</span> Type deduction<a href="#type-deduction" class="self-link"></a></h3>
<p>One of the main motivations of this proposal is to deduce the <em>cv</em>-qualifiers and value category of the class object, which requires that the explicit member object or type be deducible from the object on which the member function is invoked.</p>
<p>If the type of the object parameter is a template parameter, all of the usual template deduction rules apply as expected:</p>
<div class="sourceCode" id="cb13"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb13-1"><a href="#cb13-1"></a><span class="kw">struct</span> X <span class="op">{</span></span>
<span id="cb13-2"><a href="#cb13-2"></a>  <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> Self<span class="op">&gt;</span></span>
<span id="cb13-3"><a href="#cb13-3"></a>  <span class="dt">void</span> foo<span class="op">(</span><span class="kw">this</span> Self<span class="op">&amp;&amp;</span>, <span class="dt">int</span><span class="op">)</span>;</span>
<span id="cb13-4"><a href="#cb13-4"></a><span class="op">}</span>;</span>
<span id="cb13-5"><a href="#cb13-5"></a></span>
<span id="cb13-6"><a href="#cb13-6"></a><span class="kw">struct</span> D <span class="op">:</span> X <span class="op">{</span> <span class="op">}</span>;</span>
<span id="cb13-7"><a href="#cb13-7"></a></span>
<span id="cb13-8"><a href="#cb13-8"></a><span class="dt">void</span> ex<span class="op">(</span>X<span class="op">&amp;</span> x, D<span class="op">&amp;</span> d<span class="op">)</span> <span class="op">{</span></span>
<span id="cb13-9"><a href="#cb13-9"></a>    x<span class="op">.</span>foo<span class="op">(</span><span class="dv">1</span><span class="op">)</span>;       <span class="co">// Self=X&amp;</span></span>
<span id="cb13-10"><a href="#cb13-10"></a>    move<span class="op">(</span>x<span class="op">).</span>foo<span class="op">(</span><span class="dv">2</span><span class="op">)</span>; <span class="co">// Self=X</span></span>
<span id="cb13-11"><a href="#cb13-11"></a>    d<span class="op">.</span>foo<span class="op">(</span><span class="dv">3</span><span class="op">)</span>;       <span class="co">// Self=D&amp;</span></span>
<span id="cb13-12"><a href="#cb13-12"></a><span class="op">}</span></span></code></pre></div>
<p>It’s important to stress that deduction is able to deduce a derived type, which is extremely powerful. In the last line, regardless of syntax, <code class="sourceCode cpp">Self</code> deduces as <code class="sourceCode cpp">D<span class="op">&amp;</span></code>. This has implications for <a href="#name-lookup-within-member-functions">name lookup within member functions</a>, and leads to a potential <a href="#faq-computed-deduction">template argument deduction extension</a>.</p>
<h3 data-number="4.2.3" id="by-value-this"><span class="header-section-number">4.2.3</span> By value <code class="sourceCode cpp"><span class="kw">this</span></code><a href="#by-value-this" class="self-link"></a></h3>
<p>But what if the explicit type does not have reference type? What should this mean?</p>
<div class="sourceCode" id="cb14"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb14-1"><a href="#cb14-1"></a><span class="kw">struct</span> less_than <span class="op">{</span></span>
<span id="cb14-2"><a href="#cb14-2"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T, <span class="kw">typename</span> U<span class="op">&gt;</span></span>
<span id="cb14-3"><a href="#cb14-3"></a>    <span class="dt">bool</span> <span class="kw">operator</span><span class="op">()(</span><span class="kw">this</span> less_than, T <span class="kw">const</span><span class="op">&amp;</span> lhs, U <span class="kw">const</span><span class="op">&amp;</span> rhs<span class="op">)</span> <span class="op">{</span></span>
<span id="cb14-4"><a href="#cb14-4"></a>        <span class="cf">return</span> lhs <span class="op">&lt;</span> rhs;</span>
<span id="cb14-5"><a href="#cb14-5"></a>    <span class="op">}</span></span>
<span id="cb14-6"><a href="#cb14-6"></a><span class="op">}</span>;</span>
<span id="cb14-7"><a href="#cb14-7"></a></span>
<span id="cb14-8"><a href="#cb14-8"></a>less_than<span class="op">{}(</span><span class="dv">4</span>, <span class="dv">5</span><span class="op">)</span>;</span></code></pre></div>
<p>Clearly, the parameter specification should not lie, and the first parameter (<code class="sourceCode cpp">less_than<span class="op">{}</span></code>) is passed by value.</p>
<p>Following the proposed rules for candidate lookup, the call operator here would be a candidate, with the object parameter binding to the (empty) object and the other two parameters binding to the arguments. Having a value parameter is nothing new in the language at all — it has a clear and obvious meaning, but we’ve never been able to take an object parameter by value before. For cases in which this might be desirable, see <a href="#by-value-member-functions">by-value member functions</a>.</p>
<h3 data-number="4.2.4" id="name-lookup-within-member-functions"><span class="header-section-number">4.2.4</span> Name lookup: within member functions<a href="#name-lookup-within-member-functions" class="self-link"></a></h3>
<p>So far, we’ve only considered how member functions with explicit object parameters are found with name lookup and how they deduce that parameter. Now we move on to how the bodies of these functions actually behave.</p>
<p>Since the explicit object parameter is deduced from the object on which the function is called, this has the possible effect of deducing <em>derived</em> types. We must carefully consider how name lookup works in this context.</p>
<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">struct</span> B <span class="op">{</span></span>
<span id="cb15-2"><a href="#cb15-2"></a>    <span class="dt">int</span> i <span class="op">=</span> <span class="dv">0</span>;</span>
<span id="cb15-3"><a href="#cb15-3"></a></span>
<span id="cb15-4"><a href="#cb15-4"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> Self<span class="op">&gt;</span> <span class="kw">auto</span><span class="op">&amp;&amp;</span> f1<span class="op">(</span><span class="kw">this</span> Self<span class="op">&amp;&amp;)</span> <span class="op">{</span> <span class="cf">return</span> i;  <span class="op">}</span></span>
<span id="cb15-5"><a href="#cb15-5"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> Self<span class="op">&gt;</span> <span class="kw">auto</span><span class="op">&amp;&amp;</span> f2<span class="op">(</span><span class="kw">this</span> Self<span class="op">&amp;&amp;)</span> <span class="op">{</span> <span class="cf">return</span> <span class="kw">this</span><span class="op">-&gt;</span>i; <span class="op">}</span></span>
<span id="cb15-6"><a href="#cb15-6"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> Self<span class="op">&gt;</span> <span class="kw">auto</span><span class="op">&amp;&amp;</span> f3<span class="op">(</span><span class="kw">this</span> Self<span class="op">&amp;&amp;)</span> <span class="op">{</span> <span class="cf">return</span> forward_like<span class="op">&lt;</span>Self<span class="op">&gt;(*</span><span class="kw">this</span><span class="op">).</span>i; <span class="op">}</span></span>
<span id="cb15-7"><a href="#cb15-7"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> Self<span class="op">&gt;</span> <span class="kw">auto</span><span class="op">&amp;&amp;</span> f4<span class="op">(</span><span class="kw">this</span> Self<span class="op">&amp;&amp;)</span> <span class="op">{</span> <span class="cf">return</span> forward<span class="op">&lt;</span>Self<span class="op">&gt;(*</span><span class="kw">this</span><span class="op">).</span>i; <span class="op">}</span></span>
<span id="cb15-8"><a href="#cb15-8"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> Self<span class="op">&gt;</span> <span class="kw">auto</span><span class="op">&amp;&amp;</span> f5<span class="op">(</span><span class="kw">this</span> Self<span class="op">&amp;&amp;</span> self<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> forward<span class="op">&lt;</span>Self<span class="op">&gt;(</span>self<span class="op">).</span>i; <span class="op">}</span></span>
<span id="cb15-9"><a href="#cb15-9"></a><span class="op">}</span>;</span>
<span id="cb15-10"><a href="#cb15-10"></a></span>
<span id="cb15-11"><a href="#cb15-11"></a><span class="kw">struct</span> D <span class="op">:</span> B <span class="op">{</span></span>
<span id="cb15-12"><a href="#cb15-12"></a>    <span class="co">// shadows B::i</span></span>
<span id="cb15-13"><a href="#cb15-13"></a>    <span class="dt">double</span> i <span class="op">=</span> <span class="fl">3.14</span>;</span>
<span id="cb15-14"><a href="#cb15-14"></a><span class="op">}</span>;</span></code></pre></div>
<p>The question is, what do each of these five functions do? Should any of them be ill-formed? What is the safest option?</p>
<p>We believe that there are three approaches to choose from:</p>
<ol type="1">
<li><p>If there is an explicit object parameter, <code class="sourceCode cpp"><span class="kw">this</span></code> is inaccessible, and each access must be through <code class="sourceCode cpp">self</code>. There is no implicit lookup of members through <code class="sourceCode cpp"><span class="kw">this</span></code>. This makes <code class="sourceCode cpp">f1</code> through <code class="sourceCode cpp">f4</code> ill-formed and only <code class="sourceCode cpp">f5</code> well-formed. However, while <code class="sourceCode cpp">B<span class="op">().</span>f5<span class="op">()</span></code> returns a reference to <code class="sourceCode cpp">B<span class="op">::</span>i</code>, <code class="sourceCode cpp">D<span class="op">().</span>f5<span class="op">()</span></code> returns a reference to <code class="sourceCode cpp">D<span class="op">::</span>i</code>, since <code class="sourceCode cpp">self</code> is a reference to <code class="sourceCode cpp">D</code>.</p></li>
<li><p>If there is an explicit object parameter, <code class="sourceCode cpp"><span class="kw">this</span></code> is accessible and points to the base subobject. There is no implicit lookup of members; all access must be through <code class="sourceCode cpp"><span class="kw">this</span></code> or <code class="sourceCode cpp">self</code> explicitly. This makes <code class="sourceCode cpp">f1</code> ill-formed. <code class="sourceCode cpp">f2</code> would be well-formed and always return a reference to <code class="sourceCode cpp">B<span class="op">::</span>i</code>. Most importantly, <code class="sourceCode cpp"><span class="kw">this</span></code> would be <em>dependent</em> if the explicit object parameter was deduced. <code class="sourceCode cpp"><span class="kw">this</span><span class="op">-&gt;</span>i</code> is always going to be an <code class="sourceCode cpp"><span class="dt">int</span></code> but it could be either an <code class="sourceCode cpp"><span class="dt">int</span></code> or an <code class="sourceCode cpp"><span class="dt">int</span> <span class="kw">const</span></code> depending on whether the <code class="sourceCode cpp">B</code> object is const. <code class="sourceCode cpp">f3</code> would always be well-formed and would be the correct way to return a forwarding reference to <code class="sourceCode cpp">B<span class="op">::</span>i</code>. <code class="sourceCode cpp">f4</code> would be well-formed when invoked on <code class="sourceCode cpp">B</code> but ill-formed if invoked on <code class="sourceCode cpp">D</code> because of the requested implicit downcast. As before, <code class="sourceCode cpp">f5</code> would be well-formed.</p></li>
<li><p><code class="sourceCode cpp"><span class="kw">this</span></code> is always accessible and points to the base subobject; we allow implicit lookup as in C++17. This is mostly the same as the previous choice, except that now <code class="sourceCode cpp">f1</code> is well-formed and exactly equivalent to <code class="sourceCode cpp">f2</code>.</p></li>
</ol>
<p>Following discussion in San Diego, the option we are proposing is #1. This allows for the clearest model of what a <code class="sourceCode cpp"><span class="kw">this</span></code>-annotated function is: it is a <code class="sourceCode cpp"><span class="kw">static</span></code> member function that offers a more convenient function call syntax. There is no implicit <code class="sourceCode cpp"><span class="kw">this</span></code> in such functions, the only mention of <code class="sourceCode cpp"><span class="kw">this</span></code> would be the annotation on the object parameter. All member access must be done directly through the object parameter.</p>
<p>The consequence of such a choice is that we will need to defend against the object parameter being deduced to a derived type. To ensure that <code class="sourceCode cpp">f5<span class="op">()</span></code> above is always returning a reference to <code class="sourceCode cpp">B<span class="op">::</span>i</code>, we would need to write one of the following:</p>
<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> Self<span class="op">&gt;</span></span>
<span id="cb16-2"><a href="#cb16-2"></a><span class="kw">auto</span><span class="op">&amp;&amp;</span> f5<span class="op">(</span><span class="kw">this</span> Self<span class="op">&amp;&amp;</span> self<span class="op">)</span> <span class="op">{</span></span>
<span id="cb16-3"><a href="#cb16-3"></a>    <span class="co">// explicitly cast self to the appropriately qualified B</span></span>
<span id="cb16-4"><a href="#cb16-4"></a>    <span class="co">// note that we have to cast self, not self.i</span></span>
<span id="cb16-5"><a href="#cb16-5"></a>    <span class="cf">return</span> <span class="kw">static_cast</span><span class="op">&lt;</span>like_t<span class="op">&lt;</span>Self, B<span class="op">&gt;&amp;&amp;&gt;(</span>self<span class="op">).</span>i;</span>
<span id="cb16-6"><a href="#cb16-6"></a></span>
<span id="cb16-7"><a href="#cb16-7"></a>    <span class="co">// use the explicit subobject syntax. Note that this is always</span></span>
<span id="cb16-8"><a href="#cb16-8"></a>    <span class="co">// an lvalue reference - not a forwarding reference</span></span>
<span id="cb16-9"><a href="#cb16-9"></a>    <span class="cf">return</span> self<span class="op">.</span>B<span class="op">::</span>i;</span>
<span id="cb16-10"><a href="#cb16-10"></a></span>
<span id="cb16-11"><a href="#cb16-11"></a>    <span class="co">// use the explicit subobject syntax to get a forwarding reference</span></span>
<span id="cb16-12"><a href="#cb16-12"></a>    <span class="cf">return</span> forward<span class="op">&lt;</span>Self<span class="op">&gt;(</span>self<span class="op">).</span>B<span class="op">::</span>i;</span>
<span id="cb16-13"><a href="#cb16-13"></a><span class="op">}</span></span></code></pre></div>
<h3 data-number="4.2.5" id="the-shadowing-mitigation-private-inheritance-problem"><span class="header-section-number">4.2.5</span> The Shadowing Mitigation / Private Inheritance Problem<a href="#the-shadowing-mitigation-private-inheritance-problem" class="self-link"></a></h3>
<p>The worst case for this proposal is the case where we do <em>not</em> intend on deducing a derived object - we only mean to deduce the qualifiers - but that derived type inherits from us privately and shadows one of our members:</p>
<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">class</span> B <span class="op">{</span></span>
<span id="cb17-2"><a href="#cb17-2"></a>    <span class="dt">int</span> i;</span>
<span id="cb17-3"><a href="#cb17-3"></a><span class="kw">public</span><span class="op">:</span></span>
<span id="cb17-4"><a href="#cb17-4"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> Self<span class="op">&gt;</span></span>
<span id="cb17-5"><a href="#cb17-5"></a>    <span class="kw">auto</span><span class="op">&amp;&amp;</span> get<span class="op">(</span><span class="kw">this</span> Self<span class="op">&amp;&amp;</span> self<span class="op">)</span> <span class="op">{</span></span>
<span id="cb17-6"><a href="#cb17-6"></a>        <span class="co">// see above: we need to mitigate against shadowing</span></span>
<span id="cb17-7"><a href="#cb17-7"></a>        <span class="cf">return</span> forward<span class="op">&lt;</span>Self<span class="op">&gt;(</span>self<span class="op">).</span>B<span class="op">::</span>i;</span>
<span id="cb17-8"><a href="#cb17-8"></a>    <span class="op">}</span></span>
<span id="cb17-9"><a href="#cb17-9"></a><span class="op">}</span>;</span>
<span id="cb17-10"><a href="#cb17-10"></a></span>
<span id="cb17-11"><a href="#cb17-11"></a><span class="kw">class</span> D <span class="op">:</span> <span class="kw">private</span> B <span class="op">{</span></span>
<span id="cb17-12"><a href="#cb17-12"></a>    <span class="dt">double</span> i;</span>
<span id="cb17-13"><a href="#cb17-13"></a><span class="kw">public</span><span class="op">:</span></span>
<span id="cb17-14"><a href="#cb17-14"></a>    <span class="kw">using</span> B<span class="op">::</span>get;</span>
<span id="cb17-15"><a href="#cb17-15"></a><span class="op">}</span>;</span>
<span id="cb17-16"><a href="#cb17-16"></a></span>
<span id="cb17-17"><a href="#cb17-17"></a>D<span class="op">().</span>get<span class="op">()</span>; <span class="co">// error</span></span></code></pre></div>
<p>In this example, <code class="sourceCode cpp">Self</code> deduces as <code class="sourceCode cpp">D</code> (not <code class="sourceCode cpp">B</code>), but our choice of shadowing mitigation will not work - we cannot actually access <code class="sourceCode cpp">B<span class="op">::</span>i</code> from a <code class="sourceCode cpp">D</code> because that inheritance is private!</p>
<p>However, we don’t have to rely on <code class="sourceCode cpp">D</code> to friend <code class="sourceCode cpp">B</code> to get this to work. There actually is a way to get this to work correctly and safely. C-style casts get a bad rap, but they are actually the solution here:</p>
<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">class</span> B <span class="op">{</span></span>
<span id="cb18-2"><a href="#cb18-2"></a>    <span class="dt">int</span> i;</span>
<span id="cb18-3"><a href="#cb18-3"></a><span class="kw">public</span><span class="op">:</span></span>
<span id="cb18-4"><a href="#cb18-4"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> Self<span class="op">&gt;</span></span>
<span id="cb18-5"><a href="#cb18-5"></a>    <span class="kw">auto</span><span class="op">&amp;&amp;</span> get<span class="op">(</span><span class="kw">this</span> Self<span class="op">&amp;&amp;</span> self<span class="op">)</span> <span class="op">{</span></span>
<span id="cb18-6"><a href="#cb18-6"></a>        <span class="cf">return</span> <span class="op">((</span>like_t<span class="op">&lt;</span>Self, B<span class="op">&gt;&amp;&amp;)</span>self<span class="op">).</span>i;</span>
<span id="cb18-7"><a href="#cb18-7"></a>    <span class="op">}</span></span>
<span id="cb18-8"><a href="#cb18-8"></a><span class="op">}</span>;</span>
<span id="cb18-9"><a href="#cb18-9"></a></span>
<span id="cb18-10"><a href="#cb18-10"></a><span class="kw">class</span> D <span class="op">:</span> <span class="kw">private</span> B <span class="op">{</span></span>
<span id="cb18-11"><a href="#cb18-11"></a>    <span class="dt">double</span> i;</span>
<span id="cb18-12"><a href="#cb18-12"></a><span class="kw">public</span><span class="op">:</span></span>
<span id="cb18-13"><a href="#cb18-13"></a>    <span class="kw">using</span> B<span class="op">::</span>get;</span>
<span id="cb18-14"><a href="#cb18-14"></a><span class="op">}</span>;</span>
<span id="cb18-15"><a href="#cb18-15"></a></span>
<span id="cb18-16"><a href="#cb18-16"></a>D<span class="op">().</span>get<span class="op">()</span>; <span class="co">// now ok, and returns B::i</span></span></code></pre></div>
<p>No access checking for the win.</p>
<h3 data-number="4.2.6" id="writing-function-pointer-types"><span class="header-section-number">4.2.6</span> Writing the function pointer types for such functions<a href="#writing-function-pointer-types" class="self-link"></a></h3>
<p>As described in the previous section, the model for a member function with an explicit object parameter is a <code class="sourceCode cpp"><span class="kw">static</span></code> member function.</p>
<p>In other words, given:</p>
<div class="sourceCode" id="cb19"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb19-1"><a href="#cb19-1"></a><span class="kw">struct</span> Y <span class="op">{</span></span>
<span id="cb19-2"><a href="#cb19-2"></a>    <span class="dt">int</span> f<span class="op">(</span><span class="dt">int</span>, <span class="dt">int</span><span class="op">)</span> <span class="kw">const</span><span class="op">&amp;</span>;</span>
<span id="cb19-3"><a href="#cb19-3"></a>    <span class="dt">int</span> g<span class="op">(</span><span class="kw">this</span> Y <span class="kw">const</span><span class="op">&amp;</span>, <span class="dt">int</span>, <span class="dt">int</span><span class="op">)</span>;</span>
<span id="cb19-4"><a href="#cb19-4"></a><span class="op">}</span>;</span></code></pre></div>
<p>While the type of <code class="sourceCode cpp"><span class="op">&amp;</span>Y<span class="op">::</span>f</code> is <code class="sourceCode cpp"><span class="dt">int</span><span class="op">(</span>Y<span class="op">::*)(</span><span class="dt">int</span>, <span class="dt">int</span><span class="op">)</span> <span class="kw">const</span><span class="op">&amp;</span></code>, the type of <code class="sourceCode cpp"><span class="op">&amp;</span>Y<span class="op">::</span>g</code> is <code class="sourceCode cpp"><span class="dt">int</span><span class="op">(*)(</span>Y <span class="kw">const</span><span class="op">&amp;</span>, <span class="dt">int</span>, <span class="dt">int</span><span class="op">)</span></code>. As these are <em>just</em> function pointers, the usage of these two member functions differs once we drop them to pointers:</p>
<div class="sourceCode" id="cb20"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb20-1"><a href="#cb20-1"></a>Y y;</span>
<span id="cb20-2"><a href="#cb20-2"></a>y<span class="op">.</span>f<span class="op">(</span><span class="dv">1</span>, <span class="dv">2</span><span class="op">)</span>; <span class="co">// ok as usual</span></span>
<span id="cb20-3"><a href="#cb20-3"></a>y<span class="op">.</span>g<span class="op">(</span><span class="dv">3</span>, <span class="dv">4</span><span class="op">)</span>; <span class="co">// ok, this paper</span></span>
<span id="cb20-4"><a href="#cb20-4"></a></span>
<span id="cb20-5"><a href="#cb20-5"></a><span class="kw">auto</span> pf <span class="op">=</span> <span class="op">&amp;</span>Y<span class="op">::</span>f;</span>
<span id="cb20-6"><a href="#cb20-6"></a>pf<span class="op">(</span>y, <span class="dv">1</span>, <span class="dv">2</span><span class="op">)</span>;              <span class="co">// error: pointers to member functions are not callable</span></span>
<span id="cb20-7"><a href="#cb20-7"></a><span class="op">(</span>y<span class="op">.*</span>pf<span class="op">)(</span><span class="dv">1</span>, <span class="dv">2</span><span class="op">)</span>;            <span class="co">// okay, same as above</span></span>
<span id="cb20-8"><a href="#cb20-8"></a>std<span class="op">::</span>invoke<span class="op">(</span>pf, y, <span class="dv">1</span>, <span class="dv">2</span><span class="op">)</span>; <span class="co">// ok</span></span>
<span id="cb20-9"><a href="#cb20-9"></a></span>
<span id="cb20-10"><a href="#cb20-10"></a><span class="kw">auto</span> pg <span class="op">=</span> <span class="op">&amp;</span>Y<span class="op">::</span>g;</span>
<span id="cb20-11"><a href="#cb20-11"></a>pg<span class="op">(</span>y, <span class="dv">3</span>, <span class="dv">4</span><span class="op">)</span>;              <span class="co">// okay, same as above</span></span>
<span id="cb20-12"><a href="#cb20-12"></a><span class="op">(</span>y<span class="op">.*</span>pg<span class="op">)(</span><span class="dv">3</span>, <span class="dv">4</span><span class="op">)</span>;            <span class="co">// error: pg is not a pointer to member function</span></span>
<span id="cb20-13"><a href="#cb20-13"></a>std<span class="op">::</span>invoke<span class="op">(</span>pg, y, <span class="dv">3</span>, <span class="dv">4</span><span class="op">)</span>; <span class="co">// ok</span></span></code></pre></div>
<p>The rules are the same when deduction kicks in:</p>
<div class="sourceCode" id="cb21"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb21-1"><a href="#cb21-1"></a><span class="kw">struct</span> B <span class="op">{</span></span>
<span id="cb21-2"><a href="#cb21-2"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> Self<span class="op">&gt;</span></span>
<span id="cb21-3"><a href="#cb21-3"></a>    <span class="dt">void</span> foo<span class="op">(</span><span class="kw">this</span> Self<span class="op">&amp;&amp;)</span>;</span>
<span id="cb21-4"><a href="#cb21-4"></a><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">struct</span> D <span class="op">:</span> B <span class="op">{</span> <span class="op">}</span>;</span></code></pre></div>
<p>Types are as follows:</p>
<ul>
<li>Type of <code class="sourceCode cpp"><span class="op">&amp;</span>B<span class="op">::</span>foo<span class="op">&lt;</span>B<span class="op">&gt;</span></code> is <code class="sourceCode cpp"><span class="dt">void</span><span class="op">(*)(</span>B<span class="op">&amp;&amp;)</span></code></li>
<li>Type of <code class="sourceCode cpp"><span class="op">&amp;</span>B<span class="op">::</span>foo<span class="op">&lt;</span>B <span class="kw">const</span><span class="op">&amp;&gt;</span></code> is <code class="sourceCode cpp"><span class="dt">void</span><span class="op">(*)(</span>B <span class="kw">const</span><span class="op">&amp;)</span></code></li>
<li>Type of <code class="sourceCode cpp"><span class="op">&amp;</span>D<span class="op">::</span>foo<span class="op">&lt;</span>B<span class="op">&gt;</span></code> is <code class="sourceCode cpp"><span class="dt">void</span><span class="op">(*)(</span>B<span class="op">&amp;&amp;)</span></code></li>
<li>Type of <code class="sourceCode cpp"><span class="op">&amp;</span>B<span class="op">::</span>foo<span class="op">&lt;</span>D<span class="op">&gt;</span></code> is <code class="sourceCode cpp"><span class="dt">void</span><span class="op">(*)(</span>D<span class="op">&amp;&amp;)</span></code></li>
</ul>
<p>This is exactly what happens if <code class="sourceCode cpp">foo</code> is a normal function.</p>
<p>By-value object parameters give you pointers to function in just the same way, the only difference being that the first parameter being a value parameter instead of a reference parameter:</p>
<div class="sourceCode" id="cb22"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb22-1"><a href="#cb22-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="cb22-2"><a href="#cb22-2"></a><span class="kw">struct</span> less_than <span class="op">{</span></span>
<span id="cb22-3"><a href="#cb22-3"></a>    <span class="dt">bool</span> <span class="kw">operator</span><span class="op">()(</span><span class="kw">this</span> less_than, T <span class="kw">const</span><span class="op">&amp;</span>, T <span class="kw">const</span><span class="op">&amp;)</span>;</span>
<span id="cb22-4"><a href="#cb22-4"></a><span class="op">}</span>;</span></code></pre></div>
<p>The type of <code class="sourceCode cpp"><span class="op">&amp;</span>less_than<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;::</span><span class="kw">operator</span><span class="op">()</span></code> is <code class="sourceCode cpp"><span class="dt">bool</span><span class="op">(*)(</span>less_than<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;</span>, <span class="dt">int</span> <span class="kw">const</span><span class="op">&amp;</span>, <span class="dt">int</span> <span class="kw">const</span><span class="op">&amp;)</span></code> and follows the usual rules of invocation:</p>
<div class="sourceCode" id="cb23"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb23-1"><a href="#cb23-1"></a>less_than<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;</span> lt;</span>
<span id="cb23-2"><a href="#cb23-2"></a><span class="kw">auto</span> p <span class="op">=</span> <span class="op">&amp;</span>less_than<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;::</span><span class="kw">operator</span><span class="op">()</span>;</span>
<span id="cb23-3"><a href="#cb23-3"></a></span>
<span id="cb23-4"><a href="#cb23-4"></a>lt<span class="op">(</span><span class="dv">1</span>, <span class="dv">2</span><span class="op">)</span>;            <span class="co">// ok</span></span>
<span id="cb23-5"><a href="#cb23-5"></a>p<span class="op">(</span>lt, <span class="dv">1</span>, <span class="dv">2</span><span class="op">)</span>;         <span class="co">// ok</span></span>
<span id="cb23-6"><a href="#cb23-6"></a><span class="op">(</span>lt<span class="op">.*</span>p<span class="op">)(</span><span class="dv">1</span>, <span class="dv">2</span><span class="op">)</span>;       <span class="co">// error: p is not a pointer to member function</span></span>
<span id="cb23-7"><a href="#cb23-7"></a>invoke<span class="op">(</span>p, lt, <span class="dv">1</span>, <span class="dv">2</span><span class="op">)</span>; <span class="co">// ok</span></span></code></pre></div>
<h3 data-number="4.2.7" id="pathological-cases"><span class="header-section-number">4.2.7</span> Pathological cases<a href="#pathological-cases" class="self-link"></a></h3>
<p>It is important to mention the pathological cases. First, what happens if <code class="sourceCode cpp">D</code> is incomplete but becomes valid later?</p>
<div class="sourceCode" id="cb24"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb24-1"><a href="#cb24-1"></a><span class="kw">struct</span> D;</span>
<span id="cb24-2"><a href="#cb24-2"></a><span class="kw">struct</span> B <span class="op">{</span></span>
<span id="cb24-3"><a href="#cb24-3"></a>    <span class="dt">void</span> foo<span class="op">(</span><span class="kw">this</span> D <span class="kw">const</span><span class="op">&amp;)</span>;</span>
<span id="cb24-4"><a href="#cb24-4"></a><span class="op">}</span>;</span>
<span id="cb24-5"><a href="#cb24-5"></a><span class="kw">struct</span> D <span class="op">:</span> B <span class="op">{</span> <span class="op">}</span>;</span></code></pre></div>
<p>Following the precedent of <span class="citation" data-cites="P0929R2">[<a href="#ref-P0929R2" role="doc-biblioref">P0929R2</a>]</span>, we think this should be fine, albeit strange. If <code class="sourceCode cpp">D</code> is incomplete, we simply postpone checking until the point where we actually need a complete type, as usual. At that point <code class="sourceCode cpp">D<span class="op">().</span>foo<span class="op">()</span></code> would be a valid expression. We see no reason to reject.</p>
<p>For unrelated complete classes or non-classes:</p>
<div class="sourceCode" id="cb25"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb25-1"><a href="#cb25-1"></a><span class="kw">struct</span> A <span class="op">{</span> <span class="op">}</span>;</span>
<span id="cb25-2"><a href="#cb25-2"></a><span class="kw">struct</span> B <span class="op">{</span></span>
<span id="cb25-3"><a href="#cb25-3"></a>    <span class="dt">void</span> foo<span class="op">(</span><span class="kw">this</span> A<span class="op">&amp;)</span>;</span>
<span id="cb25-4"><a href="#cb25-4"></a>    <span class="dt">void</span> bar<span class="op">(</span><span class="kw">this</span> <span class="dt">int</span><span class="op">)</span>;</span>
<span id="cb25-5"><a href="#cb25-5"></a><span class="op">}</span>;</span></code></pre></div>
<p>These are even more unlikely to be actually useful code. In this example, <code class="sourceCode cpp">B</code> is neither convertible to <code class="sourceCode cpp">A</code> nor <code class="sourceCode cpp"><span class="dt">int</span></code>, so neither of these functions is even invocable using normal member syntax. However, you could take a pointer to such functions and invoke them through that pointer. <code class="sourceCode cpp"><span class="op">(&amp;</span>B<span class="op">::</span>bar<span class="op">)(</span><span class="dv">42</span><span class="op">)</span></code> is a valid, if weird, call.</p>
<p>We think these declarations can best be left for compilers to warn about if they so choose, rather than coming up with a language rule to reject them.</p>
<p>Another interesting case, courtesy of Jens Maurer:</p>
<div class="sourceCode" id="cb26"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb26-1"><a href="#cb26-1"></a><span class="kw">struct</span> D;</span>
<span id="cb26-2"><a href="#cb26-2"></a><span class="kw">struct</span> B <span class="op">{</span></span>
<span id="cb26-3"><a href="#cb26-3"></a>  <span class="dt">int</span> f1<span class="op">(</span><span class="kw">this</span> D<span class="op">)</span>;</span>
<span id="cb26-4"><a href="#cb26-4"></a><span class="op">}</span>;</span>
<span id="cb26-5"><a href="#cb26-5"></a><span class="kw">struct</span> D1 <span class="op">:</span> B <span class="op">{</span> <span class="op">}</span>;</span>
<span id="cb26-6"><a href="#cb26-6"></a><span class="kw">struct</span> D2 <span class="op">:</span> B <span class="op">{</span> <span class="op">}</span>;</span>
<span id="cb26-7"><a href="#cb26-7"></a><span class="kw">struct</span> D <span class="op">:</span> D1, D2 <span class="op">{</span> <span class="op">}</span>;</span>
<span id="cb26-8"><a href="#cb26-8"></a></span>
<span id="cb26-9"><a href="#cb26-9"></a><span class="dt">int</span> x <span class="op">=</span> D<span class="op">().</span>f1<span class="op">()</span>;  <span class="co">// error: ambiguous lookup</span></span>
<span id="cb26-10"><a href="#cb26-10"></a><span class="dt">int</span> y <span class="op">=</span> B<span class="op">().</span>f1<span class="op">()</span>;  <span class="co">// error: B is not implicitly convertible to D</span></span>
<span id="cb26-11"><a href="#cb26-11"></a><span class="kw">auto</span> z <span class="op">=</span> <span class="op">&amp;</span>B<span class="op">::</span>f1;   <span class="co">// ok</span></span>
<span id="cb26-12"><a href="#cb26-12"></a>z<span class="op">(</span>D<span class="op">())</span>;            <span class="co">// ok</span></span></code></pre></div>
<p>Even though both <code class="sourceCode cpp">D<span class="op">().</span>f1<span class="op">()</span></code> and <code class="sourceCode cpp">B<span class="op">().</span>f1<span class="op">()</span></code> are ill-formed, for entirely different reasons, taking a pointer to <code class="sourceCode cpp"><span class="op">&amp;</span>B<span class="op">::</span>f1</code> is acceptable — its type is <code class="sourceCode cpp"><span class="dt">int</span><span class="op">(*)(</span>D<span class="op">)</span></code> — and that function pointer can be invoked with a <code class="sourceCode cpp">D</code>. Actually invoking this function does not require any further name lookup or conversion because by-value member functions do not have an implicit object parameter in this syntax (see <a href="#by-value-this">by-value <code class="sourceCode cpp"><span class="kw">this</span></code></a>). The same reasoning holds for the direct function invocation.</p>
<p>Again, we’re not sure if these formulations are actually useful. More so that they don’t seem harmful and attempting to reject these cases may accidentally reject useful ones.</p>
<h3 data-number="4.2.8" id="teachability-implications"><span class="header-section-number">4.2.8</span> Teachability Implications<a href="#teachability-implications" class="self-link"></a></h3>
<p>Explicitly naming the object as the <code class="sourceCode cpp"><span class="kw">this</span></code>-designated first parameter fits within many programmers’ mental models of the <code class="sourceCode cpp"><span class="kw">this</span></code> pointer being the first parameter to member functions “under the hood” and is comparable to its usage in other languages, e.g. Python and Rust. It also works as a more obvious way to teach how <code class="sourceCode cpp">std<span class="op">::</span>bind</code>, <code class="sourceCode cpp">std<span class="op">::</span>thread</code>, <code class="sourceCode cpp">std<span class="op">::</span>function</code>, and others work with a member function pointer by making the pointer explicit.</p>
<p>As such, we do not believe there to be any teachability problems.</p>
<h3 data-number="4.2.9" id="static-member-functions"><span class="header-section-number">4.2.9</span> Can <code class="sourceCode cpp"><span class="kw">static</span></code> member functions have an explicit object type?<a href="#static-member-functions" class="self-link"></a></h3>
<p>No. Static member functions currently do not have an implicit object parameter, and therefore have no reason to provide an explicit one.</p>
<h3 data-number="4.2.10" id="interplays-with-capturing-this"><span class="header-section-number">4.2.10</span> Interplays with capturing <code class="sourceCode cpp"><span class="op">[</span><span class="kw">this</span><span class="op">]</span></code> and <code class="sourceCode cpp"><span class="op">[*</span><span class="kw">this</span><span class="op">]</span></code> in lambdas<a href="#interplays-with-capturing-this" class="self-link"></a></h3>
<p>Interoperability is perfect, since they do not impact the meaning of <code class="sourceCode cpp"><span class="kw">this</span></code> in a function body. The introduced identifier <code class="sourceCode cpp">self</code> can then be used to refer to the lambda instance from the body.</p>
<h3 data-number="4.2.11" id="parsing-issues"><span class="header-section-number">4.2.11</span> Parsing issues<a href="#parsing-issues" class="self-link"></a></h3>
<p>The proposed syntax has no parsings issue that we are aware of.</p>
<h3 data-number="4.2.12" id="code-issues"><span class="header-section-number">4.2.12</span> Code issues<a href="#code-issues" class="self-link"></a></h3>
<p>There are two programmatic issues with this proposal that we are aware of:</p>
<ol type="1">
<li><p>Inadvertently referencing a shadowing member of a derived object in a base class <code class="sourceCode cpp"><span class="kw">this</span></code>-annotated member function. There are some use cases where we would want to do this on purpose (see <a href="#crtp">crtp</a>), but for other use-cases the programmer will have to be aware of potential issues and defend against them in a somewhat verbose way.</p></li>
<li><p>Because there is no way to <em>just</em> deduce <code class="sourceCode cpp"><span class="kw">const</span></code> vs non-<code class="sourceCode cpp"><span class="kw">const</span></code>, the only way to deduce the value category would be to take a forwarding reference. This means that potentially we create four instantiations when only two would be minimally necessary to solve the problem. But deferring to a templated implementation is an acceptable option and has been improved by no longer requiring casts. We believe that the problem is minimal.</p></li>
</ol>
<h2 data-number="4.3" id="not-quite-static-not-quite-non-static"><span class="header-section-number">4.3</span> Not quite static, not quite non-static<a href="#not-quite-static-not-quite-non-static" class="self-link"></a></h2>
<p>The status quo is that all member functions are either static member functions or non-static member functions. A member function with an explicit object parameter (see the <a href="#overview">wording overview</a> for why “object parameter” rather than “this parameter” or something else) is a third kind of member function that’s sort of halfway in between those two. They’re like semi-static member functions. We’ll call them explicit object member functions due to them having an explicit object parameter. You can think of regular non-static member functions as being implicit object member functions.</p>
<p>The high level overview of the design is that from the <em>outside</em>, an explicit object member function looks and behaves as much like a non-static member function as possible. You can’t take an lvalue to such a member, they have to be invoked like non-static member functions, etc. But from the <em>inside</em>, an explicit object member function behaves exactly like a static member function: there is no implicit <code class="sourceCode cpp"><span class="kw">this</span></code>, your only access to the class object is through the explicit object parameter. The difference is still observable — a pointer to such a function has pointer to function type rather than pointer to member type, but that’s about the extent of it.</p>
<p>Some examples of distinctions:</p>
<div class="sourceCode" id="cb27"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb27-1"><a href="#cb27-1"></a><span class="kw">struct</span> C <span class="op">{</span></span>
<span id="cb27-2"><a href="#cb27-2"></a>    <span class="dt">void</span> nonstatic_fun<span class="op">()</span>;</span>
<span id="cb27-3"><a href="#cb27-3"></a>    </span>
<span id="cb27-4"><a href="#cb27-4"></a>    <span class="dt">void</span> explicit_fun<span class="op">(</span><span class="kw">this</span> C c<span class="op">)</span> <span class="op">{</span></span>
<span id="cb27-5"><a href="#cb27-5"></a>        <span class="kw">auto</span> x <span class="op">=</span> <span class="kw">this</span>;      <span class="co">// error: no this</span></span>
<span id="cb27-6"><a href="#cb27-6"></a>        nonstatic_fun<span class="op">()</span>;    <span class="co">// error: no implicit this-&gt;, non-static member function needs an object</span></span>
<span id="cb27-7"><a href="#cb27-7"></a>        c<span class="op">.</span>nonstatic_fun<span class="op">()</span>;  <span class="co">// ok</span></span>
<span id="cb27-8"><a href="#cb27-8"></a>        </span>
<span id="cb27-9"><a href="#cb27-9"></a>        static_fun<span class="op">(</span>C<span class="op">{})</span>;    <span class="co">// ok</span></span>
<span id="cb27-10"><a href="#cb27-10"></a>        <span class="op">(+</span>static_fun<span class="op">)(</span>C<span class="op">{})</span>; <span class="co">// ok</span></span>
<span id="cb27-11"><a href="#cb27-11"></a>    <span class="op">}</span></span>
<span id="cb27-12"><a href="#cb27-12"></a>    </span>
<span id="cb27-13"><a href="#cb27-13"></a>    <span class="kw">static</span> <span class="dt">void</span> static_fun<span class="op">(</span>C<span class="op">)</span> <span class="op">{</span></span>
<span id="cb27-14"><a href="#cb27-14"></a>        explicit_fun<span class="op">()</span>;        <span class="co">// error: needs an object</span></span>
<span id="cb27-15"><a href="#cb27-15"></a>        explicit_fun<span class="op">(</span>C<span class="op">{})</span>;     <span class="co">// error: not the right way to provide an object</span></span>
<span id="cb27-16"><a href="#cb27-16"></a>        <span class="kw">auto</span> f <span class="op">=</span> explicit_fun; <span class="co">// error: can&#39;t just name such a function, must invoke it</span></span>
<span id="cb27-17"><a href="#cb27-17"></a>        <span class="op">(+</span>explicit_fun<span class="op">)(</span>C<span class="op">{})</span>;  <span class="co">// error: can&#39;t convert the name to a pointer</span></span>
<span id="cb27-18"><a href="#cb27-18"></a>        </span>
<span id="cb27-19"><a href="#cb27-19"></a>        C<span class="op">{}.</span>explicit_fun<span class="op">()</span>;        <span class="co">// ok</span></span>
<span id="cb27-20"><a href="#cb27-20"></a>        <span class="kw">auto</span> p <span class="op">=</span> explicit_fun;     <span class="co">// error: as above</span></span>
<span id="cb27-21"><a href="#cb27-21"></a>        <span class="kw">auto</span> q <span class="op">=</span> <span class="op">&amp;</span>explicit_fun;    <span class="co">// error: can&#39;t take a unqualified reference either</span></span>
<span id="cb27-22"><a href="#cb27-22"></a>        <span class="kw">auto</span> r <span class="op">=</span> <span class="op">&amp;</span>C<span class="op">::</span>explicit_fun; <span class="co">// ok</span></span>
<span id="cb27-23"><a href="#cb27-23"></a>        r<span class="op">(</span>C<span class="op">{})</span>;                    <span class="co">// ok</span></span>
<span id="cb27-24"><a href="#cb27-24"></a>    <span class="op">}</span></span>
<span id="cb27-25"><a href="#cb27-25"></a>    </span>
<span id="cb27-26"><a href="#cb27-26"></a>    <span class="kw">static</span> <span class="dt">void</span> <span class="kw">operator</span><span class="op">()(</span><span class="dt">int</span><span class="op">)</span>;   <span class="co">// error: call operator still can&#39;t be static</span></span>
<span id="cb27-27"><a href="#cb27-27"></a>    <span class="dt">void</span> <span class="kw">operator</span><span class="op">()(</span><span class="kw">this</span> C, <span class="dt">char</span><span class="op">)</span>; <span class="co">// ok</span></span>
<span id="cb27-28"><a href="#cb27-28"></a><span class="op">}</span>;</span>
<span id="cb27-29"><a href="#cb27-29"></a></span>
<span id="cb27-30"><a href="#cb27-30"></a>C c;</span>
<span id="cb27-31"><a href="#cb27-31"></a><span class="dt">int</span> <span class="op">(*</span>a<span class="op">)(</span>C<span class="op">)</span> <span class="op">=</span> <span class="op">&amp;</span>C<span class="op">::</span>explicit_fun; <span class="co">// ok</span></span>
<span id="cb27-32"><a href="#cb27-32"></a><span class="dt">int</span> <span class="op">(*</span>b<span class="op">)(</span>C<span class="op">)</span> <span class="op">=</span> C<span class="op">::</span>explicit_fun;  <span class="co">// error: can&#39;t just name such a function, must invoke it</span></span>
<span id="cb27-33"><a href="#cb27-33"></a></span>
<span id="cb27-34"><a href="#cb27-34"></a><span class="kw">auto</span> x <span class="op">=</span> c<span class="op">.</span>static_fun;     <span class="co">// ok</span></span>
<span id="cb27-35"><a href="#cb27-35"></a><span class="kw">auto</span> y <span class="op">=</span> c<span class="op">.</span>explicit_fun;   <span class="co">// error: can&#39;t just name such a function, must invoke it</span></span>
<span id="cb27-36"><a href="#cb27-36"></a><span class="kw">auto</span> z <span class="op">=</span> c<span class="op">.</span>explicit_fun<span class="op">()</span>; <span class="co">// ok</span></span></code></pre></div>
<p>The question is: should we describe these new functions as a new kind of <em>static</em> member function or as a new kind of <em>non-static</em> member function? For the sake of this small section, I’m going to refer to the three kinds of functions as either “legacy static” (status quo static member functions), “legacy non-static” (status quo non-static member functions), or “explicit this” (the ones introduced in this paper).</p>
<p>If we go through several salient aspects of legacy static and legacy non-static member functions, we can see how explicit this functions fare:</p>
<table>
<thead>
<tr>
<th>
</th>
<th>
legacy non-static
</th>
<th>
explicit this
</th>
<th>
legacy static
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
Requires/uses an object argument
</td>
<td style="background-color:#acf2bd">
Yes
</td>
<td style="background-color:#acf2bd">
Yes
</td>
<td style="background-color:#ff8888">
No
</td>
</tr>
<tr>
<td>
Has implicit <code class="sourceCode cpp"><span class="kw">this</span></code>
</td>
<td style="background-color:#acf2bd">
Yes
</td>
<td style="background-color:#ff8888">
No
</td>
<td style="background-color:#ff8888">
No
</td>
</tr>
<tr>
<td>
Can be used to declare operators
</td>
<td style="background-color:#acf2bd">
Yes
</td>
<td style="background-color:#acf2bd">
Yes
</td>
<td style="background-color:#ff8888">
No
</td>
</tr>
<tr>
<td>
Type of <code class="sourceCode cpp"><span class="op">&amp;</span>C<span class="op">::</span>f</code>
</td>
<td style="background-color:#acf2bd">
Pointer-to-Member
</td>
<td style="background-color:#ff8888">
Pointer-to-Function
</td>
<td style="background-color:#ff8888">
Pointer-to-Function
</td>
</tr>
<tr>
<td>
Does <code class="sourceCode cpp"><span class="kw">auto</span> f <span class="op">=</span> x<span class="op">.</span>f;</code> work?
</td>
<td style="background-color:#acf2bd">
No
</td>
<td style="background-color:#acf2bd">
No
</td>
<td style="background-color:#ff8888">
Yes
</td>
</tr>
<tr>
<td>
Can the name decay to a function pointer?
</td>
<td style="background-color:#acf2bd">
No
</td>
<td style="background-color:#acf2bd">
No
</td>
<td style="background-color:#ff8888">
Yes
</td>
</tr>
<tr>
<td>
Can it be virtual
</td>
<td style="background-color:#acf2bd">
Yes
</td>
<td style="background-color:yellow">
<a href="#explicit-object-parameter-and-virtual">Maybe</a>
</td>
<td style="background-color:#ff8888">
No
</td>
</tr>
</tbody>
</table>
<p>If we consider an explicit object member function as being a static member function, as have to answer the question of what to do with the <code class="sourceCode cpp"><span class="kw">static</span></code> keyword:</p>
<div class="sourceCode" id="cb28"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb28-1"><a href="#cb28-1"></a><span class="kw">struct</span> C <span class="op">{</span></span>
<span id="cb28-2"><a href="#cb28-2"></a>    <span class="dt">void</span> f<span class="op">(</span><span class="kw">this</span> C <span class="kw">const</span><span class="op">&amp;)</span>;          <span class="co">// proposed ok</span></span>
<span id="cb28-3"><a href="#cb28-3"></a>    <span class="kw">static</span> <span class="dt">void</span> g<span class="op">(</span><span class="kw">this</span> C <span class="kw">const</span><span class="op">&amp;)</span>;   <span class="co">// what about this?</span></span>
<span id="cb28-4"><a href="#cb28-4"></a><span class="op">}</span>;</span></code></pre></div>
<p>If <code class="sourceCode cpp">C<span class="op">::</span>f</code> is static, then either <code class="sourceCode cpp">C<span class="op">::</span>g</code> is redundantly static (so the keyword does nothing?) or ill-formed (so the keyword breaks code?). From the user’s perspective, <code class="sourceCode cpp">g</code> behaves like a non-static member function. It needs to be invoked on an object, and it should not matter in most cases whether <code class="sourceCode cpp">g</code> is implemented with an explicit or implicit object parameter. Annoting such a function as <code class="sourceCode cpp"><span class="kw">static</span></code> is potentially misleading as it suggests an entirely different usage pattern. We still have to use it as <code class="sourceCode cpp">c<span class="op">.</span>g<span class="op">()</span></code> while <code class="sourceCode cpp">C<span class="op">::</span>g<span class="op">(</span>c<span class="op">)</span></code> is ill-formed.</p>
<p>Or we go the reverse and say that <code class="sourceCode cpp">C<span class="op">::</span>f</code> is actually ill-formed and say that you <em>have</em> to annotate it as <code class="sourceCode cpp"><span class="kw">static</span></code> (meaning this feature actually requires two keywords: <code class="sourceCode cpp"><span class="kw">static</span></code> and <code class="sourceCode cpp"><span class="kw">this</span></code>). But mandating <code class="sourceCode cpp"><span class="kw">static</span></code> doesn’t work well with lambdas:</p>
<div class="sourceCode" id="cb29"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb29-1"><a href="#cb29-1"></a><span class="op">[](</span><span class="kw">this</span> <span class="kw">auto</span> self<span class="op">)</span> <span class="kw">static</span> <span class="op">{</span> <span class="op">...</span> <span class="op">}</span></span></code></pre></div>
<p>But we’re not especially used to writing these specifiers after the lambda’s declarator. <code class="sourceCode cpp"><span class="kw">constexpr</span></code> is implicit, so is not necessary to write. <code class="sourceCode cpp"><span class="kw">consteval</span></code> is too new to have much feedback on yet. Mandating <code class="sourceCode cpp"><span class="kw">static</span></code> here seems actively harmful, while making it optional seems to provide no benefit.</p>
<p>As described <a href="#explicit-object-parameter-and-virtual">later</a>, while explicit object member functions cannot be <code class="sourceCode cpp"><span class="kw">virtual</span></code> with this proposal, it is possible that they could be in the future. So annotating them as <code class="sourceCode cpp"><span class="kw">static</span></code> would be exceedingly misleading in this sense.</p>
<p>As a result of all of the above, this paper proposes that:</p>
<ul>
<li>a member function declared with an explicit <code class="sourceCode cpp"><span class="kw">this</span></code> parameter (i.e. an explicit object member function) is a non-static member function,</li>
<li>an explicit object member function cannot be declared <code class="sourceCode cpp"><span class="kw">static</span></code> (i.e. it really is a <em>non-static</em> member function),</li>
<li>an explicit object member function cannot be <code class="sourceCode cpp"><span class="kw">virtual</span></code> (see later section)</li>
<li>a legacy non-static member function will be called an implicit object member function</li>
</ul>
<p>Having gone through the wording for this proposal both considering explicit object member functions as static and non-static, there are a lot more rules that apply to both implicit and explicit object member functions (to the exclusion of static member functions) than there are that apply to both C++17 static member functions and explicit object member functions. As such, the amount of wording to be done is also smaller if we consider explicit object member functions as non-static.</p>
<h3 data-number="4.3.1" id="implicit-this-access"><span class="header-section-number">4.3.1</span> Implicit this access<a href="#implicit-this-access" class="self-link"></a></h3>
<p>One question came up over the course of implementing this feature which was whether or not there should be implicit this syntax for invoking an explicit object member function from an implicit object member function. That is:</p>
<div class="sourceCode" id="cb30"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb30-1"><a href="#cb30-1"></a><span class="kw">struct</span> D <span class="op">{</span></span>
<span id="cb30-2"><a href="#cb30-2"></a>    <span class="dt">void</span> explicit_fun<span class="op">(</span><span class="kw">this</span> D <span class="kw">const</span><span class="op">&amp;)</span>;</span>
<span id="cb30-3"><a href="#cb30-3"></a>    </span>
<span id="cb30-4"><a href="#cb30-4"></a>    <span class="dt">void</span> implicit_fun<span class="op">()</span> <span class="kw">const</span> <span class="op">{</span></span>
<span id="cb30-5"><a href="#cb30-5"></a>        <span class="kw">this</span><span class="op">-&gt;</span>explicit_fun<span class="op">()</span>; <span class="co">// obviously ok</span></span>
<span id="cb30-6"><a href="#cb30-6"></a>        explicit_fun<span class="op">()</span>;       <span class="co">// but what about this?</span></span>
<span id="cb30-7"><a href="#cb30-7"></a>    <span class="op">}</span></span>
<span id="cb30-8"><a href="#cb30-8"></a><span class="op">}</span>;</span></code></pre></div>
<p>It’s tempting to say that given an <em>explicit</em> object parameter, we should always require an <em>explicit</em> object argument. But one of the major advantages of having the “implicit this” call support in this context is that it allows derived types to not have to know about the implementation choice. As frequently used as a motivating example, we would like <code class="sourceCode cpp">std<span class="op">::</span>optional</code> to be able to implement its member functions using this language feature if it wants to, without us having to know about it:</p>
<div class="sourceCode" id="cb31"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb31-1"><a href="#cb31-1"></a><span class="kw">struct</span> F <span class="op">:</span> std<span class="op">::</span>optional<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;</span></span>
<span id="cb31-2"><a href="#cb31-2"></a><span class="op">{</span></span>
<span id="cb31-3"><a href="#cb31-3"></a>    <span class="dt">bool</span> is_big<span class="op">()</span> <span class="kw">const</span> <span class="op">{</span></span>
<span id="cb31-4"><a href="#cb31-4"></a>        <span class="co">// if this language feature required explicit call syntax, then this</span></span>
<span id="cb31-5"><a href="#cb31-5"></a>        <span class="co">// call would be valid if and only if the particular implementation of</span></span>
<span id="cb31-6"><a href="#cb31-6"></a>        <span class="co">// optional did _not_ use this feature. This is undesirable</span></span>
<span id="cb31-7"><a href="#cb31-7"></a>        <span class="cf">return</span> value<span class="op">()</span> <span class="op">&gt;</span> <span class="dv">42</span>;</span>
<span id="cb31-8"><a href="#cb31-8"></a>    <span class="op">}</span></span>
<span id="cb31-9"><a href="#cb31-9"></a><span class="op">}</span>;</span></code></pre></div>
<p>Or, more generally, the implementation strategy of a particular type’s member function should not be relevant for users deriving from that type. So “implicit this” stays.</p>
<h3 data-number="4.3.2" id="explicit-object-parameter-and-virtual"><span class="header-section-number">4.3.2</span> Explicit object parameter and virtual<a href="#explicit-object-parameter-and-virtual" class="self-link"></a></h3>
<p>In this proposal, member functions with an explicit object parameter cannot be <code class="sourceCode cpp"><span class="kw">virtual</span></code>. But explicit object member functions are intended to be a substitute for implicit object member functions, so why not?</p>
<p>Many of the motivating use-cases for this feature involve templates, which make the question of whether or not to allow virtual moot. However, several people have expressed an interest in using such syntax as their sole choice for writing any non-static member functions as a style choice. While we are not here to endorse or reject any particular style choice, we should at least consider to what extent this proposal can support them.</p>
<p>To that end, the question of allowing explicit object member functions to be virtual comes up. Consider:</p>
<div class="sourceCode" id="cb32"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb32-1"><a href="#cb32-1"></a><span class="kw">struct</span> B <span class="op">{</span></span>
<span id="cb32-2"><a href="#cb32-2"></a>    <span class="kw">virtual</span> <span class="dt">void</span> f<span class="op">()</span>; <span class="co">// no ref-qualifier</span></span>
<span id="cb32-3"><a href="#cb32-3"></a><span class="op">}</span>;</span>
<span id="cb32-4"><a href="#cb32-4"></a></span>
<span id="cb32-5"><a href="#cb32-5"></a><span class="kw">struct</span> D <span class="op">:</span> B <span class="op">{</span></span>
<span id="cb32-6"><a href="#cb32-6"></a>    <span class="dt">void</span> f<span class="op">(</span><span class="kw">this</span> D<span class="op">&amp;)</span> <span class="kw">override</span>; <span class="co">// ok?</span></span>
<span id="cb32-7"><a href="#cb32-7"></a><span class="op">}</span>;</span></code></pre></div>
<p>There are two potential issues with this approach.</p>
<p>The first is that these really do mean slightly different things. <code class="sourceCode cpp">B<span class="op">().</span>f<span class="op">()</span></code> is a valid expression. While <code class="sourceCode cpp">B<span class="op">::</span>f</code>’s implicit object parameter has type <code class="sourceCode cpp">B<span class="op">&amp;</span></code>, it can be invoked with any value category of <code class="sourceCode cpp">B</code>. But <code class="sourceCode cpp">D<span class="op">().</span>f<span class="op">()</span></code> is ill-formed, we have no such value category carve-out for the explicit object parameter.</p>
<p>This particular issue doesn’t seem terribly problematic, since the ability to invoke virtual member functions on rvalues of (statically) derived type isn’t really the primary (or any kind of) motivation for virtual functions. But it is an issue.</p>
<p>The second, and larger, issue is a question of calling convention. What would the calling convention be? If the calling convention of an explicit object member function is the same as that of a free function, would the virtual dispatch work by generating a forwarding thunk to do calling convention adjustment or would we emit <code class="sourceCode cpp">D<span class="op">::</span>f</code> twice with two different calling conventions? Or, if the calling convention is the same as that of a member function, do we introduce a generalized pointer-to-member function type to properly account for by-value object parameters? Calling convention mismatch is a problem, and introducing a new kind of pointer-to-member type seems like a fairly large and potentially viral change.</p>
<p>Notably, neither of these problems exist if we only allow overrides of the same <em>kind</em> of member function. That is, explicit object member functions can only override other explicit object member functions and implicit object member functions can only override other implicit object member functions:</p>
<div class="sourceCode" id="cb33"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb33-1"><a href="#cb33-1"></a><span class="kw">struct</span> B2 <span class="op">{</span></span>
<span id="cb33-2"><a href="#cb33-2"></a>    <span class="kw">virtual</span> <span class="dt">void</span> f<span class="op">()</span>;</span>
<span id="cb33-3"><a href="#cb33-3"></a>    <span class="kw">virtual</span> <span class="dt">void</span> g<span class="op">(</span><span class="kw">this</span> B2 <span class="kw">const</span><span class="op">&amp;</span>, <span class="dt">int</span><span class="op">)</span>;</span>
<span id="cb33-4"><a href="#cb33-4"></a><span class="op">}</span>;</span>
<span id="cb33-5"><a href="#cb33-5"></a></span>
<span id="cb33-6"><a href="#cb33-6"></a><span class="kw">struct</span> D2 <span class="op">:</span> B2 <span class="op">{</span></span>
<span id="cb33-7"><a href="#cb33-7"></a>    <span class="dt">void</span> f<span class="op">()</span> <span class="kw">override</span>;                    <span class="co">// ok</span></span>
<span id="cb33-8"><a href="#cb33-8"></a>    <span class="dt">void</span> f<span class="op">(</span><span class="kw">this</span> D2 <span class="kw">const</span><span class="op">&amp;)</span> <span class="kw">override</span>;      <span class="co">// error</span></span>
<span id="cb33-9"><a href="#cb33-9"></a>    </span>
<span id="cb33-10"><a href="#cb33-10"></a>    <span class="dt">void</span> g<span class="op">(</span><span class="dt">int</span><span class="op">)</span> <span class="kw">const</span><span class="op">&amp;</span> <span class="kw">override</span>;          <span class="co">// error</span></span>
<span id="cb33-11"><a href="#cb33-11"></a>    <span class="dt">void</span> g<span class="op">(</span><span class="kw">this</span> D2 <span class="kw">const</span><span class="op">&amp;</span>, <span class="dt">int</span><span class="op">)</span> <span class="kw">override</span>; <span class="co">// ok</span></span>
<span id="cb33-12"><a href="#cb33-12"></a><span class="op">}</span>;</span></code></pre></div>
<p>Such a direction would introduce a second observable difference between implicit and explicit object member functions: the type of a pointer to such a function and the override mechanism.</p>
<p>However, such a direction also doesn’t provide the user with any ability that they didn’t have before. It would purely be a style choice. As such, we don’t consider the question of allowing <code class="sourceCode cpp"><span class="kw">virtual</span></code> to be especially important at this time.</p>
<p>Note that the paper currently allows this:</p>
<div class="sourceCode" id="cb34"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb34-1"><a href="#cb34-1"></a><span class="kw">struct</span> B3 <span class="op">{</span></span>
<span id="cb34-2"><a href="#cb34-2"></a>    <span class="kw">virtual</span> <span class="dt">void</span> f<span class="op">()</span>;</span>
<span id="cb34-3"><a href="#cb34-3"></a><span class="op">}</span>;</span>
<span id="cb34-4"><a href="#cb34-4"></a></span>
<span id="cb34-5"><a href="#cb34-5"></a><span class="kw">struct</span> D3 <span class="op">:</span> B3 <span class="op">{</span></span>
<span id="cb34-6"><a href="#cb34-6"></a>    <span class="dt">void</span> f<span class="op">(</span><span class="kw">this</span> D3<span class="op">&amp;)</span>; <span class="co">// ok, does not override B3::f</span></span>
<span id="cb34-7"><a href="#cb34-7"></a><span class="op">}</span>;</span></code></pre></div>
<p>So while this keeps the door open to a future extension that would allow explicit object member functions to be <code class="sourceCode cpp"><span class="kw">virtual</span></code>, it would only allow same-kind overriding going forward (since allowing mixed-kind overriding could potentially change the meaning of code written between now and then).</p>
<h1 data-number="5" style="border-bottom:1px solid #cccccc" id="real-world-examples"><span class="header-section-number">5</span> Real-World Examples<a href="#real-world-examples" class="self-link"></a></h1>
<p>What follows are several examples of the kinds of problems that can be solved using this proposal.</p>
<h2 data-number="5.1" id="deduplicating-code"><span class="header-section-number">5.1</span> Deduplicating Code<a href="#deduplicating-code" class="self-link"></a></h2>
<p>This proposal can de-duplicate and de-quadruplicate a large amount of code. In each case, the single function is only slightly more complex than the initial two or four, which makes for a huge win. What follows are a few examples of ways to reduce repeated code.</p>
<p>This particular implementation of <code class="sourceCode cpp">optional</code> is Simon’s, and can be viewed on <a href="https://github.com/TartanLlama/optional">GitHub</a>. It includes some functions proposed in <span class="citation" data-cites="P0798R0">[<a href="#ref-P0798R0" role="doc-biblioref">P0798R0</a>]</span>, with minor changes to better suit this format:</p>
<table style="width:100%">
<tr>
<th style="width:50%">
C++17
</th>
<th style="width:50%">
Proposed
</th>
</tr>
<tr>
<td>
<div class="sourceCode" id="cb35"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb35-1"><a href="#cb35-1"></a><span class="kw">class</span> TextBlock <span class="op">{</span></span>
<span id="cb35-2"><a href="#cb35-2"></a><span class="kw">public</span><span class="op">:</span></span>
<span id="cb35-3"><a href="#cb35-3"></a>  <span class="dt">char</span> <span class="kw">const</span><span class="op">&amp;</span> <span class="kw">operator</span><span class="op">[](</span><span class="dt">size_t</span> position<span class="op">)</span> <span class="kw">const</span> <span class="op">{</span></span>
<span id="cb35-4"><a href="#cb35-4"></a>    <span class="co">// ...</span></span>
<span id="cb35-5"><a href="#cb35-5"></a>    <span class="cf">return</span> text<span class="op">[</span>position<span class="op">]</span>;</span>
<span id="cb35-6"><a href="#cb35-6"></a>  <span class="op">}</span></span>
<span id="cb35-7"><a href="#cb35-7"></a></span>
<span id="cb35-8"><a href="#cb35-8"></a>  <span class="dt">char</span><span class="op">&amp;</span> <span class="kw">operator</span><span class="op">[](</span><span class="dt">size_t</span> position<span class="op">)</span> <span class="op">{</span></span>
<span id="cb35-9"><a href="#cb35-9"></a>    <span class="cf">return</span> <span class="kw">const_cast</span><span class="op">&lt;</span><span class="dt">char</span><span class="op">&amp;&gt;(</span></span>
<span id="cb35-10"><a href="#cb35-10"></a>      <span class="kw">static_cast</span><span class="op">&lt;</span>TextBlock <span class="kw">const</span><span class="op">&amp;&gt;</span></span>
<span id="cb35-11"><a href="#cb35-11"></a>        <span class="op">(</span><span class="kw">this</span><span class="op">)[</span>position<span class="op">]</span></span>
<span id="cb35-12"><a href="#cb35-12"></a>    <span class="op">)</span>;</span>
<span id="cb35-13"><a href="#cb35-13"></a>  <span class="op">}</span></span>
<span id="cb35-14"><a href="#cb35-14"></a>  <span class="co">// ...</span></span>
<span id="cb35-15"><a href="#cb35-15"></a><span class="op">}</span>;</span></code></pre></div>
</td>
<td>
<div class="sourceCode" id="cb36"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb36-1"><a href="#cb36-1"></a><span class="kw">class</span> TextBlock <span class="op">{</span></span>
<span id="cb36-2"><a href="#cb36-2"></a><span class="kw">public</span><span class="op">:</span></span>
<span id="cb36-3"><a href="#cb36-3"></a>  <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> Self<span class="op">&gt;</span></span>
<span id="cb36-4"><a href="#cb36-4"></a>  <span class="kw">auto</span><span class="op">&amp;</span> <span class="kw">operator</span><span class="op">[](</span><span class="kw">this</span> Self<span class="op">&amp;&amp;</span> self, <span class="dt">size_t</span> position<span class="op">)</span> <span class="op">{</span></span>
<span id="cb36-5"><a href="#cb36-5"></a>    <span class="co">// ...</span></span>
<span id="cb36-6"><a href="#cb36-6"></a>    <span class="cf">return</span> self<span class="op">.</span>text<span class="op">[</span>position<span class="op">]</span>;</span>
<span id="cb36-7"><a href="#cb36-7"></a>  <span class="op">}</span></span>
<span id="cb36-8"><a href="#cb36-8"></a>  <span class="co">// ...</span></span>
<span id="cb36-9"><a href="#cb36-9"></a><span class="op">}</span>;</span></code></pre></div>
</td>
</tr>
<tr>
<td>
<div class="sourceCode" id="cb37"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb37-1"><a href="#cb37-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="cb37-2"><a href="#cb37-2"></a><span class="kw">class</span> optional <span class="op">{</span></span>
<span id="cb37-3"><a href="#cb37-3"></a>  <span class="co">// ...</span></span>
<span id="cb37-4"><a href="#cb37-4"></a>  <span class="kw">constexpr</span> T<span class="op">*</span> <span class="kw">operator</span><span class="op">-&gt;()</span> <span class="op">{</span></span>
<span id="cb37-5"><a href="#cb37-5"></a>    <span class="cf">return</span> addressof<span class="op">(</span><span class="kw">this</span><span class="op">-&gt;</span>m_value<span class="op">)</span>;</span>
<span id="cb37-6"><a href="#cb37-6"></a>  <span class="op">}</span></span>
<span id="cb37-7"><a href="#cb37-7"></a></span>
<span id="cb37-8"><a href="#cb37-8"></a>  <span class="kw">constexpr</span> T <span class="kw">const</span><span class="op">*</span></span>
<span id="cb37-9"><a href="#cb37-9"></a>  <span class="kw">operator</span><span class="op">-&gt;()</span> <span class="kw">const</span> <span class="op">{</span></span>
<span id="cb37-10"><a href="#cb37-10"></a>    <span class="cf">return</span> addressof<span class="op">(</span><span class="kw">this</span><span class="op">-&gt;</span>m_value<span class="op">)</span>;</span>
<span id="cb37-11"><a href="#cb37-11"></a>  <span class="op">}</span></span>
<span id="cb37-12"><a href="#cb37-12"></a>  <span class="co">// ...</span></span>
<span id="cb37-13"><a href="#cb37-13"></a><span class="op">}</span>;</span></code></pre></div>
</td>
<td>
<div class="sourceCode" id="cb38"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb38-1"><a href="#cb38-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="cb38-2"><a href="#cb38-2"></a><span class="kw">class</span> optional <span class="op">{</span></span>
<span id="cb38-3"><a href="#cb38-3"></a>  <span class="co">// ...</span></span>
<span id="cb38-4"><a href="#cb38-4"></a>  <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> Self<span class="op">&gt;</span></span>
<span id="cb38-5"><a href="#cb38-5"></a>  <span class="kw">constexpr</span> <span class="kw">auto</span> <span class="kw">operator</span><span class="op">-&gt;(</span><span class="kw">this</span> Self<span class="op">&amp;&amp;</span> self<span class="op">)</span> <span class="op">{</span></span>
<span id="cb38-6"><a href="#cb38-6"></a>    <span class="cf">return</span> addressof<span class="op">(</span>self<span class="op">.</span>m_value<span class="op">)</span>;</span>
<span id="cb38-7"><a href="#cb38-7"></a>  <span class="op">}</span></span>
<span id="cb38-8"><a href="#cb38-8"></a>  <span class="co">// ...</span></span>
<span id="cb38-9"><a href="#cb38-9"></a><span class="op">}</span>;</span></code></pre></div>
</td>
</tr>
<tr>
<td>
<div class="sourceCode" id="cb39"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb39-1"><a href="#cb39-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="cb39-2"><a href="#cb39-2"></a><span class="kw">class</span> optional <span class="op">{</span></span>
<span id="cb39-3"><a href="#cb39-3"></a>  <span class="co">// ...</span></span>
<span id="cb39-4"><a href="#cb39-4"></a>  <span class="kw">constexpr</span> T<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">*()</span> <span class="op">&amp;</span> <span class="op">{</span></span>
<span id="cb39-5"><a href="#cb39-5"></a>    <span class="cf">return</span> <span class="kw">this</span><span class="op">-&gt;</span>m_value;</span>
<span id="cb39-6"><a href="#cb39-6"></a>  <span class="op">}</span></span>
<span id="cb39-7"><a href="#cb39-7"></a></span>
<span id="cb39-8"><a href="#cb39-8"></a>  <span class="kw">constexpr</span> T <span class="kw">const</span><span class="op">&amp;</span> <span class="kw">operator</span><span class="op">*()</span> <span class="kw">const</span><span class="op">&amp;</span> <span class="op">{</span></span>
<span id="cb39-9"><a href="#cb39-9"></a>    <span class="cf">return</span> <span class="kw">this</span><span class="op">-&gt;</span>m_value;</span>
<span id="cb39-10"><a href="#cb39-10"></a>  <span class="op">}</span></span>
<span id="cb39-11"><a href="#cb39-11"></a></span>
<span id="cb39-12"><a href="#cb39-12"></a>  <span class="kw">constexpr</span> T<span class="op">&amp;&amp;</span> <span class="kw">operator</span><span class="op">*()</span> <span class="op">&amp;&amp;</span> <span class="op">{</span></span>
<span id="cb39-13"><a href="#cb39-13"></a>    <span class="cf">return</span> move<span class="op">(</span><span class="kw">this</span><span class="op">-&gt;</span>m_value<span class="op">)</span>;</span>
<span id="cb39-14"><a href="#cb39-14"></a>  <span class="op">}</span></span>
<span id="cb39-15"><a href="#cb39-15"></a></span>
<span id="cb39-16"><a href="#cb39-16"></a>  <span class="kw">constexpr</span> T <span class="kw">const</span><span class="op">&amp;&amp;</span></span>
<span id="cb39-17"><a href="#cb39-17"></a>  <span class="kw">operator</span><span class="op">*()</span> <span class="kw">const</span><span class="op">&amp;&amp;</span> <span class="op">{</span></span>
<span id="cb39-18"><a href="#cb39-18"></a>    <span class="cf">return</span> move<span class="op">(</span><span class="kw">this</span><span class="op">-&gt;</span>m_value<span class="op">)</span>;</span>
<span id="cb39-19"><a href="#cb39-19"></a>  <span class="op">}</span></span>
<span id="cb39-20"><a href="#cb39-20"></a></span>
<span id="cb39-21"><a href="#cb39-21"></a>  <span class="kw">constexpr</span> T<span class="op">&amp;</span> value<span class="op">()</span> <span class="op">&amp;</span> <span class="op">{</span></span>
<span id="cb39-22"><a href="#cb39-22"></a>    <span class="cf">if</span> <span class="op">(</span>has_value<span class="op">())</span> <span class="op">{</span></span>
<span id="cb39-23"><a href="#cb39-23"></a>      <span class="cf">return</span> <span class="kw">this</span><span class="op">-&gt;</span>m_value;</span>
<span id="cb39-24"><a href="#cb39-24"></a>    <span class="op">}</span></span>
<span id="cb39-25"><a href="#cb39-25"></a>    <span class="cf">throw</span> bad_optional_access<span class="op">()</span>;</span>
<span id="cb39-26"><a href="#cb39-26"></a>  <span class="op">}</span></span>
<span id="cb39-27"><a href="#cb39-27"></a></span>
<span id="cb39-28"><a href="#cb39-28"></a>  <span class="kw">constexpr</span> T <span class="kw">const</span><span class="op">&amp;</span> value<span class="op">()</span> <span class="kw">const</span><span class="op">&amp;</span> <span class="op">{</span></span>
<span id="cb39-29"><a href="#cb39-29"></a>    <span class="cf">if</span> <span class="op">(</span>has_value<span class="op">())</span> <span class="op">{</span></span>
<span id="cb39-30"><a href="#cb39-30"></a>      <span class="cf">return</span> <span class="kw">this</span><span class="op">-&gt;</span>m_value;</span>
<span id="cb39-31"><a href="#cb39-31"></a>    <span class="op">}</span></span>
<span id="cb39-32"><a href="#cb39-32"></a>    <span class="cf">throw</span> bad_optional_access<span class="op">()</span>;</span>
<span id="cb39-33"><a href="#cb39-33"></a>  <span class="op">}</span></span>
<span id="cb39-34"><a href="#cb39-34"></a></span>
<span id="cb39-35"><a href="#cb39-35"></a>  <span class="kw">constexpr</span> T<span class="op">&amp;&amp;</span> value<span class="op">()</span> <span class="op">&amp;&amp;</span> <span class="op">{</span></span>
<span id="cb39-36"><a href="#cb39-36"></a>    <span class="cf">if</span> <span class="op">(</span>has_value<span class="op">())</span> <span class="op">{</span></span>
<span id="cb39-37"><a href="#cb39-37"></a>      <span class="cf">return</span> move<span class="op">(</span><span class="kw">this</span><span class="op">-&gt;</span>m_value<span class="op">)</span>;</span>
<span id="cb39-38"><a href="#cb39-38"></a>    <span class="op">}</span></span>
<span id="cb39-39"><a href="#cb39-39"></a>    <span class="cf">throw</span> bad_optional_access<span class="op">()</span>;</span>
<span id="cb39-40"><a href="#cb39-40"></a>  <span class="op">}</span></span>
<span id="cb39-41"><a href="#cb39-41"></a></span>
<span id="cb39-42"><a href="#cb39-42"></a>  <span class="kw">constexpr</span> T <span class="kw">const</span><span class="op">&amp;&amp;</span> value<span class="op">()</span> <span class="kw">const</span><span class="op">&amp;&amp;</span> <span class="op">{</span></span>
<span id="cb39-43"><a href="#cb39-43"></a>    <span class="cf">if</span> <span class="op">(</span>has_value<span class="op">())</span> <span class="op">{</span></span>
<span id="cb39-44"><a href="#cb39-44"></a>      <span class="cf">return</span> move<span class="op">(</span><span class="kw">this</span><span class="op">-&gt;</span>m_value<span class="op">)</span>;</span>
<span id="cb39-45"><a href="#cb39-45"></a>    <span class="op">}</span></span>
<span id="cb39-46"><a href="#cb39-46"></a>    <span class="cf">throw</span> bad_optional_access<span class="op">()</span>;</span>
<span id="cb39-47"><a href="#cb39-47"></a>  <span class="op">}</span></span>
<span id="cb39-48"><a href="#cb39-48"></a>  <span class="co">// ...</span></span>
<span id="cb39-49"><a href="#cb39-49"></a><span class="op">}</span>;</span></code></pre></div>
</td>
<td>
<div class="sourceCode" id="cb40"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb40-1"><a href="#cb40-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="cb40-2"><a href="#cb40-2"></a><span class="kw">class</span> optional <span class="op">{</span></span>
<span id="cb40-3"><a href="#cb40-3"></a>  <span class="co">// ...</span></span>
<span id="cb40-4"><a href="#cb40-4"></a>  <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> Self<span class="op">&gt;</span></span>
<span id="cb40-5"><a href="#cb40-5"></a>  <span class="kw">constexpr</span> like_t<span class="op">&lt;</span>Self, T<span class="op">&gt;&amp;&amp;</span> <span class="kw">operator</span><span class="op">*(</span><span class="kw">this</span> Self<span class="op">&amp;&amp;</span> self<span class="op">)</span> <span class="op">{</span></span>
<span id="cb40-6"><a href="#cb40-6"></a>    <span class="cf">return</span> forward<span class="op">&lt;</span>Self<span class="op">&gt;(</span>self<span class="op">).</span>m_value;</span>
<span id="cb40-7"><a href="#cb40-7"></a>  <span class="op">}</span></span>
<span id="cb40-8"><a href="#cb40-8"></a></span>
<span id="cb40-9"><a href="#cb40-9"></a>  <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> Self<span class="op">&gt;</span></span>
<span id="cb40-10"><a href="#cb40-10"></a>  <span class="kw">constexpr</span> like_t<span class="op">&lt;</span>Self, T<span class="op">&gt;&amp;&amp;</span> value<span class="op">(</span><span class="kw">this</span> Self<span class="op">&amp;&amp;</span> self<span class="op">)</span> <span class="op">{</span></span>
<span id="cb40-11"><a href="#cb40-11"></a>    <span class="cf">if</span> <span class="op">(</span>self<span class="op">.</span>has_value<span class="op">())</span> <span class="op">{</span></span>
<span id="cb40-12"><a href="#cb40-12"></a>      <span class="cf">return</span> forward<span class="op">&lt;</span>Self<span class="op">&gt;(</span>self<span class="op">).</span>m_value;</span>
<span id="cb40-13"><a href="#cb40-13"></a>    <span class="op">}</span></span>
<span id="cb40-14"><a href="#cb40-14"></a>    <span class="cf">throw</span> bad_optional_access<span class="op">()</span>;</span>
<span id="cb40-15"><a href="#cb40-15"></a>  <span class="op">}</span></span>
<span id="cb40-16"><a href="#cb40-16"></a>  <span class="co">// ...</span></span>
<span id="cb40-17"><a href="#cb40-17"></a><span class="op">}</span>;</span></code></pre></div>
</td>
</tr>
<tr>
<td>
<div class="sourceCode" id="cb41"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb41-1"><a href="#cb41-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="cb41-2"><a href="#cb41-2"></a><span class="kw">class</span> optional <span class="op">{</span></span>
<span id="cb41-3"><a href="#cb41-3"></a>  <span class="co">// ...</span></span>
<span id="cb41-4"><a href="#cb41-4"></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="cb41-5"><a href="#cb41-5"></a>  <span class="kw">constexpr</span> <span class="kw">auto</span> and_then<span class="op">(</span>F<span class="op">&amp;&amp;</span> f<span class="op">)</span> <span class="op">&amp;</span> <span class="op">{</span></span>
<span id="cb41-6"><a href="#cb41-6"></a>    <span class="kw">using</span> result <span class="op">=</span></span>
<span id="cb41-7"><a href="#cb41-7"></a>      invoke_result_t<span class="op">&lt;</span>F, T<span class="op">&amp;&gt;</span>;</span>
<span id="cb41-8"><a href="#cb41-8"></a>    <span class="kw">static_assert</span><span class="op">(</span></span>
<span id="cb41-9"><a href="#cb41-9"></a>      is_optional<span class="op">&lt;</span>result<span class="op">&gt;::</span>value,</span>
<span id="cb41-10"><a href="#cb41-10"></a>      <span class="st">&quot;F must return an optional&quot;</span><span class="op">)</span>;</span>
<span id="cb41-11"><a href="#cb41-11"></a></span>
<span id="cb41-12"><a href="#cb41-12"></a>    <span class="cf">return</span> has_value<span class="op">()</span></span>
<span id="cb41-13"><a href="#cb41-13"></a>        <span class="op">?</span> invoke<span class="op">(</span>forward<span class="op">&lt;</span>F<span class="op">&gt;(</span>f<span class="op">)</span>, <span class="op">**</span><span class="kw">this</span><span class="op">)</span></span>
<span id="cb41-14"><a href="#cb41-14"></a>        <span class="op">:</span> nullopt;</span>
<span id="cb41-15"><a href="#cb41-15"></a>  <span class="op">}</span></span>
<span id="cb41-16"><a href="#cb41-16"></a></span>
<span id="cb41-17"><a href="#cb41-17"></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="cb41-18"><a href="#cb41-18"></a>  <span class="kw">constexpr</span> <span class="kw">auto</span> and_then<span class="op">(</span>F<span class="op">&amp;&amp;</span> f<span class="op">)</span> <span class="op">&amp;&amp;</span> <span class="op">{</span></span>
<span id="cb41-19"><a href="#cb41-19"></a>    <span class="kw">using</span> result <span class="op">=</span></span>
<span id="cb41-20"><a href="#cb41-20"></a>      invoke_result_t<span class="op">&lt;</span>F, T<span class="op">&amp;&amp;&gt;</span>;</span>
<span id="cb41-21"><a href="#cb41-21"></a>    <span class="kw">static_assert</span><span class="op">(</span></span>
<span id="cb41-22"><a href="#cb41-22"></a>      is_optional<span class="op">&lt;</span>result<span class="op">&gt;::</span>value,</span>
<span id="cb41-23"><a href="#cb41-23"></a>      <span class="st">&quot;F must return an optional&quot;</span><span class="op">)</span>;</span>
<span id="cb41-24"><a href="#cb41-24"></a></span>
<span id="cb41-25"><a href="#cb41-25"></a>    <span class="cf">return</span> has_value<span class="op">()</span></span>
<span id="cb41-26"><a href="#cb41-26"></a>        <span class="op">?</span> invoke<span class="op">(</span>forward<span class="op">&lt;</span>F<span class="op">&gt;(</span>f<span class="op">)</span>,</span>
<span id="cb41-27"><a href="#cb41-27"></a>                 move<span class="op">(**</span><span class="kw">this</span><span class="op">))</span></span>
<span id="cb41-28"><a href="#cb41-28"></a>        <span class="op">:</span> nullopt;</span>
<span id="cb41-29"><a href="#cb41-29"></a>  <span class="op">}</span></span>
<span id="cb41-30"><a href="#cb41-30"></a></span>
<span id="cb41-31"><a href="#cb41-31"></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="cb41-32"><a href="#cb41-32"></a>  <span class="kw">constexpr</span> <span class="kw">auto</span> and_then<span class="op">(</span>F<span class="op">&amp;&amp;</span> f<span class="op">)</span> <span class="kw">const</span><span class="op">&amp;</span> <span class="op">{</span></span>
<span id="cb41-33"><a href="#cb41-33"></a>    <span class="kw">using</span> result <span class="op">=</span></span>
<span id="cb41-34"><a href="#cb41-34"></a>      invoke_result_t<span class="op">&lt;</span>F, T <span class="kw">const</span><span class="op">&amp;&gt;</span>;</span>
<span id="cb41-35"><a href="#cb41-35"></a>    <span class="kw">static_assert</span><span class="op">(</span></span>
<span id="cb41-36"><a href="#cb41-36"></a>      is_optional<span class="op">&lt;</span>result<span class="op">&gt;::</span>value,</span>
<span id="cb41-37"><a href="#cb41-37"></a>      <span class="st">&quot;F must return an optional&quot;</span><span class="op">)</span>;</span>
<span id="cb41-38"><a href="#cb41-38"></a></span>
<span id="cb41-39"><a href="#cb41-39"></a>    <span class="cf">return</span> has_value<span class="op">()</span></span>
<span id="cb41-40"><a href="#cb41-40"></a>        <span class="op">?</span> invoke<span class="op">(</span>forward<span class="op">&lt;</span>F<span class="op">&gt;(</span>f<span class="op">)</span>, <span class="op">**</span><span class="kw">this</span><span class="op">)</span></span>
<span id="cb41-41"><a href="#cb41-41"></a>        <span class="op">:</span> nullopt;</span>
<span id="cb41-42"><a href="#cb41-42"></a>  <span class="op">}</span></span>
<span id="cb41-43"><a href="#cb41-43"></a></span>
<span id="cb41-44"><a href="#cb41-44"></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="cb41-45"><a href="#cb41-45"></a>  <span class="kw">constexpr</span> <span class="kw">auto</span> and_then<span class="op">(</span>F<span class="op">&amp;&amp;</span> f<span class="op">)</span> <span class="kw">const</span><span class="op">&amp;&amp;</span> <span class="op">{</span></span>
<span id="cb41-46"><a href="#cb41-46"></a>    <span class="kw">using</span> result <span class="op">=</span></span>
<span id="cb41-47"><a href="#cb41-47"></a>      invoke_result_t<span class="op">&lt;</span>F, T <span class="kw">const</span><span class="op">&amp;&amp;&gt;</span>;</span>
<span id="cb41-48"><a href="#cb41-48"></a>    <span class="kw">static_assert</span><span class="op">(</span></span>
<span id="cb41-49"><a href="#cb41-49"></a>      is_optional<span class="op">&lt;</span>result<span class="op">&gt;::</span>value,</span>
<span id="cb41-50"><a href="#cb41-50"></a>      <span class="st">&quot;F must return an optional&quot;</span><span class="op">)</span>;</span>
<span id="cb41-51"><a href="#cb41-51"></a></span>
<span id="cb41-52"><a href="#cb41-52"></a>    <span class="cf">return</span> has_value<span class="op">()</span></span>
<span id="cb41-53"><a href="#cb41-53"></a>        <span class="op">?</span> invoke<span class="op">(</span>forward<span class="op">&lt;</span>F<span class="op">&gt;(</span>f<span class="op">)</span>,</span>
<span id="cb41-54"><a href="#cb41-54"></a>                 move<span class="op">(**</span><span class="kw">this</span><span class="op">))</span></span>
<span id="cb41-55"><a href="#cb41-55"></a>        <span class="op">:</span> nullopt;</span>
<span id="cb41-56"><a href="#cb41-56"></a>  <span class="op">}</span></span>
<span id="cb41-57"><a href="#cb41-57"></a>  <span class="co">// ...</span></span>
<span id="cb41-58"><a href="#cb41-58"></a><span class="op">}</span>;</span></code></pre></div>
</td>
<td>
<div class="sourceCode" id="cb42"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb42-1"><a href="#cb42-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="cb42-2"><a href="#cb42-2"></a><span class="kw">class</span> optional <span class="op">{</span></span>
<span id="cb42-3"><a href="#cb42-3"></a>  <span class="co">// ...</span></span>
<span id="cb42-4"><a href="#cb42-4"></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>
<span id="cb42-5"><a href="#cb42-5"></a>  <span class="kw">constexpr</span> <span class="kw">auto</span> and_then<span class="op">(</span><span class="kw">this</span> Self<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="cb42-6"><a href="#cb42-6"></a>    <span class="kw">using</span> val <span class="op">=</span> <span class="kw">decltype</span><span class="op">((</span></span>
<span id="cb42-7"><a href="#cb42-7"></a>        forward<span class="op">&lt;</span>Self<span class="op">&gt;(</span>self<span class="op">).</span>m_value<span class="op">))</span>;</span>
<span id="cb42-8"><a href="#cb42-8"></a>    <span class="kw">using</span> result <span class="op">=</span> invoke_result_t<span class="op">&lt;</span>F, val<span class="op">&gt;</span>;</span>
<span id="cb42-9"><a href="#cb42-9"></a></span>
<span id="cb42-10"><a href="#cb42-10"></a>    <span class="kw">static_assert</span><span class="op">(</span></span>
<span id="cb42-11"><a href="#cb42-11"></a>      is_optional<span class="op">&lt;</span>result<span class="op">&gt;::</span>value,</span>
<span id="cb42-12"><a href="#cb42-12"></a>      <span class="st">&quot;F must return an optional&quot;</span><span class="op">)</span>;</span>
<span id="cb42-13"><a href="#cb42-13"></a></span>
<span id="cb42-14"><a href="#cb42-14"></a>    <span class="cf">return</span> self<span class="op">.</span>has_value<span class="op">()</span></span>
<span id="cb42-15"><a href="#cb42-15"></a>        <span class="op">?</span> invoke<span class="op">(</span>forward<span class="op">&lt;</span>F<span class="op">&gt;(</span>f<span class="op">)</span>,</span>
<span id="cb42-16"><a href="#cb42-16"></a>                 forward<span class="op">&lt;</span>Self<span class="op">&gt;(</span>self<span class="op">).</span>m_value<span class="op">)</span></span>
<span id="cb42-17"><a href="#cb42-17"></a>        <span class="op">:</span> nullopt;</span>
<span id="cb42-18"><a href="#cb42-18"></a>  <span class="op">}</span></span>
<span id="cb42-19"><a href="#cb42-19"></a>  <span class="co">// ...</span></span>
<span id="cb42-20"><a href="#cb42-20"></a><span class="op">}</span>;</span></code></pre></div>
</td>
</tr>
</table>
<p>There are a few more functions in <span class="citation" data-cites="P0798R0">[<a href="#ref-P0798R0" role="doc-biblioref">P0798R0</a>]</span> responsible for this explosion of overloads, so the difference in both code and clarity is dramatic.</p>
<p>For those that dislike returning auto in these cases, it is easy to write a metafunction matching the appropriate qualifiers from a type. It is certainly a better option than blindly copying and pasting code, hoping that the minor changes were made correctly in each case.</p>
<h2 data-number="5.2" id="crtp"><span class="header-section-number">5.2</span> CRTP, without the C, R, or even T<a href="#crtp" class="self-link"></a></h2>
<p>Today, a common design pattern is the Curiously Recurring Template Pattern. This implies passing the derived type as a template parameter to a base class template as a way of achieving static polymorphism. If we wanted to simply outsource implementing postfix incrementation to a base, we could use CRTP for that. But with explicit objects that already deduce to the derived objects, we don’t need any curious recurrence — we can use standard inheritance and let deduction do its thing. The base class doesn’t even need to be a template:</p>
<table style="width:100%">
<tr>
<th style="width:50%">
C++17
</th>
<th style="width:50%">
Proposed
</th>
</tr>
<tr>
<td>
<div class="sourceCode" id="cb43"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb43-1"><a href="#cb43-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> Derived<span class="op">&gt;</span></span>
<span id="cb43-2"><a href="#cb43-2"></a><span class="kw">struct</span> add_postfix_increment <span class="op">{</span></span>
<span id="cb43-3"><a href="#cb43-3"></a>    Derived <span class="kw">operator</span><span class="op">++(</span><span class="dt">int</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb43-4"><a href="#cb43-4"></a>        <span class="kw">auto</span><span class="op">&amp;</span> self <span class="op">=</span> <span class="kw">static_cast</span><span class="op">&lt;</span>Derived<span class="op">&amp;&gt;(*</span><span class="kw">this</span><span class="op">)</span>;</span>
<span id="cb43-5"><a href="#cb43-5"></a></span>
<span id="cb43-6"><a href="#cb43-6"></a>        Derived tmp<span class="op">(</span>self<span class="op">)</span>;</span>
<span id="cb43-7"><a href="#cb43-7"></a>        <span class="op">++</span>self;</span>
<span id="cb43-8"><a href="#cb43-8"></a>        <span class="cf">return</span> tmp;</span>
<span id="cb43-9"><a href="#cb43-9"></a>    <span class="op">}</span></span>
<span id="cb43-10"><a href="#cb43-10"></a><span class="op">}</span>;</span>
<span id="cb43-11"><a href="#cb43-11"></a></span>
<span id="cb43-12"><a href="#cb43-12"></a><span class="kw">struct</span> some_type <span class="op">:</span> add_postfix_increment<span class="op">&lt;</span>some_type<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb43-13"><a href="#cb43-13"></a>    some_type<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">++()</span> <span class="op">{</span> <span class="op">...</span> <span class="op">}</span></span>
<span id="cb43-14"><a href="#cb43-14"></a><span class="op">}</span>;</span></code></pre></div>
</td>
<td>
<div class="sourceCode" id="cb44"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb44-1"><a href="#cb44-1"></a><span class="kw">struct</span> add_postfix_increment <span class="op">{</span></span>
<span id="cb44-2"><a href="#cb44-2"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> Self<span class="op">&gt;</span></span>
<span id="cb44-3"><a href="#cb44-3"></a>    <span class="kw">auto</span> <span class="kw">operator</span><span class="op">++(</span><span class="kw">this</span> Self<span class="op">&amp;&amp;</span> self, <span class="dt">int</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb44-4"><a href="#cb44-4"></a>        <span class="kw">auto</span> tmp <span class="op">=</span> self;</span>
<span id="cb44-5"><a href="#cb44-5"></a>        <span class="op">++</span>self;</span>
<span id="cb44-6"><a href="#cb44-6"></a>        <span class="cf">return</span> tmp;</span>
<span id="cb44-7"><a href="#cb44-7"></a>    <span class="op">}</span></span>
<span id="cb44-8"><a href="#cb44-8"></a><span class="op">}</span>;</span>
<span id="cb44-9"><a href="#cb44-9"></a></span>
<span id="cb44-10"><a href="#cb44-10"></a></span>
<span id="cb44-11"><a href="#cb44-11"></a></span>
<span id="cb44-12"><a href="#cb44-12"></a><span class="kw">struct</span> some_type <span class="op">:</span> add_postfix_increment <span class="op">{</span></span>
<span id="cb44-13"><a href="#cb44-13"></a>    some_type<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">++()</span> <span class="op">{</span> <span class="op">...</span> <span class="op">}</span></span>
<span id="cb44-14"><a href="#cb44-14"></a><span class="op">}</span>;</span></code></pre></div>
</td>
</tr>
</table>
<p>The proposed examples aren’t much shorter, but they are certainly simpler by comparison.</p>
<h3 data-number="5.2.1" id="builder-pattern"><span class="header-section-number">5.2.1</span> Builder pattern<a href="#builder-pattern" class="self-link"></a></h3>
<p>Once we start to do any more with CRTP, complexity quickly increases, whereas with this proposal, it stays remarkably low.</p>
<p>Let’s say we have a builder that does multiple things. We might start with:</p>
<div class="sourceCode" id="cb45"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb45-1"><a href="#cb45-1"></a><span class="kw">struct</span> Builder <span class="op">{</span></span>
<span id="cb45-2"><a href="#cb45-2"></a>  Builder<span class="op">&amp;</span> a<span class="op">()</span> <span class="op">{</span> <span class="co">/* ... */</span>; <span class="cf">return</span> <span class="op">*</span><span class="kw">this</span>; <span class="op">}</span></span>
<span id="cb45-3"><a href="#cb45-3"></a>  Builder<span class="op">&amp;</span> b<span class="op">()</span> <span class="op">{</span> <span class="co">/* ... */</span>; <span class="cf">return</span> <span class="op">*</span><span class="kw">this</span>; <span class="op">}</span></span>
<span id="cb45-4"><a href="#cb45-4"></a>  Builder<span class="op">&amp;</span> c<span class="op">()</span> <span class="op">{</span> <span class="co">/* ... */</span>; <span class="cf">return</span> <span class="op">*</span><span class="kw">this</span>; <span class="op">}</span></span>
<span id="cb45-5"><a href="#cb45-5"></a><span class="op">}</span>;</span>
<span id="cb45-6"><a href="#cb45-6"></a></span>
<span id="cb45-7"><a href="#cb45-7"></a>Builder<span class="op">().</span>a<span class="op">().</span>b<span class="op">().</span>a<span class="op">().</span>b<span class="op">().</span>c<span class="op">()</span>;</span></code></pre></div>
<p>But now we want to create a specialized builder with new operations <code class="sourceCode cpp">d<span class="op">()</span></code> and <code class="sourceCode cpp">e<span class="op">()</span></code>. This specialized builder needs new member functions, and we don’t want to burden existing users with them. We also want <code class="sourceCode cpp">Special<span class="op">().</span>a<span class="op">().</span>d<span class="op">()</span></code> to work, so we need to use CRTP to <em>conditionally</em> return either a <code class="sourceCode cpp">Builder<span class="op">&amp;</span></code> or a <code class="sourceCode cpp">Special<span class="op">&amp;</span></code>:</p>
<table style="width:100%">
<tr>
<th style="width:50%">
C++17
</th>
<th style="width:50%">
Proposed
</th>
</tr>
<tr>
<td>
<div class="sourceCode" id="cb46"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb46-1"><a href="#cb46-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> D<span class="op">=</span><span class="dt">void</span><span class="op">&gt;</span></span>
<span id="cb46-2"><a href="#cb46-2"></a><span class="kw">class</span> Builder <span class="op">{</span></span>
<span id="cb46-3"><a href="#cb46-3"></a>  <span class="kw">using</span> Derived <span class="op">=</span> conditional_t<span class="op">&lt;</span>is_void_v<span class="op">&lt;</span>D<span class="op">&gt;</span>, Builder, D<span class="op">&gt;</span>;</span>
<span id="cb46-4"><a href="#cb46-4"></a>  Derived<span class="op">&amp;</span> self<span class="op">()</span> <span class="op">{</span></span>
<span id="cb46-5"><a href="#cb46-5"></a>    <span class="cf">return</span> <span class="op">*</span><span class="kw">static_cast</span><span class="op">&lt;</span>Derived<span class="op">*&gt;(</span><span class="kw">this</span><span class="op">)</span>;</span>
<span id="cb46-6"><a href="#cb46-6"></a>  <span class="op">}</span></span>
<span id="cb46-7"><a href="#cb46-7"></a></span>
<span id="cb46-8"><a href="#cb46-8"></a><span class="kw">public</span><span class="op">:</span></span>
<span id="cb46-9"><a href="#cb46-9"></a>  Derived<span class="op">&amp;</span> a<span class="op">()</span> <span class="op">{</span> <span class="co">/* ... */</span>; <span class="cf">return</span> self<span class="op">()</span>; <span class="op">}</span></span>
<span id="cb46-10"><a href="#cb46-10"></a>  Derived<span class="op">&amp;</span> b<span class="op">()</span> <span class="op">{</span> <span class="co">/* ... */</span>; <span class="cf">return</span> self<span class="op">()</span>; <span class="op">}</span></span>
<span id="cb46-11"><a href="#cb46-11"></a>  Derived<span class="op">&amp;</span> c<span class="op">()</span> <span class="op">{</span> <span class="co">/* ... */</span>; <span class="cf">return</span> self<span class="op">()</span>; <span class="op">}</span></span>
<span id="cb46-12"><a href="#cb46-12"></a><span class="op">}</span>;</span>
<span id="cb46-13"><a href="#cb46-13"></a></span>
<span id="cb46-14"><a href="#cb46-14"></a><span class="kw">struct</span> Special <span class="op">:</span> Builder<span class="op">&lt;</span>Special<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb46-15"><a href="#cb46-15"></a>  Special<span class="op">&amp;</span> d<span class="op">()</span> <span class="op">{</span> <span class="co">/* ... */</span>; <span class="cf">return</span> <span class="op">*</span><span class="kw">this</span>; <span class="op">}</span></span>
<span id="cb46-16"><a href="#cb46-16"></a>  Special<span class="op">&amp;</span> e<span class="op">()</span> <span class="op">{</span> <span class="co">/* ... */</span>; <span class="cf">return</span> <span class="op">*</span><span class="kw">this</span>; <span class="op">}</span></span>
<span id="cb46-17"><a href="#cb46-17"></a><span class="op">}</span>;</span>
<span id="cb46-18"><a href="#cb46-18"></a></span>
<span id="cb46-19"><a href="#cb46-19"></a>Builder<span class="op">().</span>a<span class="op">().</span>b<span class="op">().</span>a<span class="op">().</span>b<span class="op">().</span>c<span class="op">()</span>;</span>
<span id="cb46-20"><a href="#cb46-20"></a>Special<span class="op">().</span>a<span class="op">().</span>d<span class="op">().</span>e<span class="op">().</span>a<span class="op">()</span>;</span></code></pre></div>
</td>
<td>
<div class="sourceCode" id="cb47"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb47-1"><a href="#cb47-1"></a><span class="kw">struct</span> Builder <span class="op">{</span></span>
<span id="cb47-2"><a href="#cb47-2"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> Self<span class="op">&gt;</span></span>
<span id="cb47-3"><a href="#cb47-3"></a>    Self<span class="op">&amp;</span> a<span class="op">(</span><span class="kw">this</span> Self<span class="op">&amp;&amp;</span> self<span class="op">)</span> <span class="op">{</span> <span class="co">/* ... */</span>; <span class="cf">return</span> self; <span class="op">}</span></span>
<span id="cb47-4"><a href="#cb47-4"></a></span>
<span id="cb47-5"><a href="#cb47-5"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> Self<span class="op">&gt;</span></span>
<span id="cb47-6"><a href="#cb47-6"></a>    Self<span class="op">&amp;</span> b<span class="op">(</span><span class="kw">this</span> Self<span class="op">&amp;&amp;</span> self<span class="op">)</span> <span class="op">{</span> <span class="co">/* ... */</span>; <span class="cf">return</span> self; <span class="op">}</span></span>
<span id="cb47-7"><a href="#cb47-7"></a></span>
<span id="cb47-8"><a href="#cb47-8"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> Self<span class="op">&gt;</span></span>
<span id="cb47-9"><a href="#cb47-9"></a>    Self<span class="op">&amp;</span> c<span class="op">(</span><span class="kw">this</span> Self<span class="op">&amp;&amp;</span> self<span class="op">)</span> <span class="op">{</span> <span class="co">/* ... */</span>; <span class="cf">return</span> self; <span class="op">}</span></span>
<span id="cb47-10"><a href="#cb47-10"></a><span class="op">}</span>;</span>
<span id="cb47-11"><a href="#cb47-11"></a></span>
<span id="cb47-12"><a href="#cb47-12"></a><span class="kw">struct</span> Special <span class="op">:</span> Builder <span class="op">{</span></span>
<span id="cb47-13"><a href="#cb47-13"></a>    Special<span class="op">&amp;</span> d<span class="op">()</span> <span class="op">{</span> <span class="co">/* ... */</span>; <span class="cf">return</span> <span class="op">*</span><span class="kw">this</span>; <span class="op">}</span></span>
<span id="cb47-14"><a href="#cb47-14"></a>    Special<span class="op">&amp;</span> e<span class="op">()</span> <span class="op">{</span> <span class="co">/* ... */</span>; <span class="cf">return</span> <span class="op">*</span><span class="kw">this</span>; <span class="op">}</span></span>
<span id="cb47-15"><a href="#cb47-15"></a><span class="op">}</span>;</span>
<span id="cb47-16"><a href="#cb47-16"></a></span>
<span id="cb47-17"><a href="#cb47-17"></a>Builder<span class="op">().</span>a<span class="op">().</span>b<span class="op">().</span>a<span class="op">().</span>b<span class="op">().</span>c<span class="op">()</span>;</span>
<span id="cb47-18"><a href="#cb47-18"></a>Special<span class="op">().</span>a<span class="op">().</span>d<span class="op">().</span>e<span class="op">().</span>a<span class="op">()</span>;</span></code></pre></div>
</td>
</tr>
</table>
<p>The code on the right is dramatically easier to understand and therefore more accessible to more programmers than the code on the left.</p>
<p>But wait! There’s more!</p>
<p>What if we added a <em>super</em>-specialized builder, a more special form of <code class="sourceCode cpp">Special</code>? Now we need <code class="sourceCode cpp">Special</code> to opt-in to CRTP so that it knows which type to pass to <code class="sourceCode cpp">Builder</code>, ensuring that everything in the hierarchy returns the correct type. It’s about this point that most programmers would give up. But with this proposal, there’s no problem!</p>
<table style="width:100%">
<tr>
<th style="width:50%">
C++17
</th>
<th style="width:50%">
Proposed
</th>
</tr>
<tr>
<td>
<div class="sourceCode" id="cb48"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb48-1"><a href="#cb48-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> D<span class="op">=</span><span class="dt">void</span><span class="op">&gt;</span></span>
<span id="cb48-2"><a href="#cb48-2"></a><span class="kw">class</span> Builder <span class="op">{</span></span>
<span id="cb48-3"><a href="#cb48-3"></a><span class="kw">protected</span><span class="op">:</span></span>
<span id="cb48-4"><a href="#cb48-4"></a>  <span class="kw">using</span> Derived <span class="op">=</span> conditional_t<span class="op">&lt;</span>is_void_v<span class="op">&lt;</span>D<span class="op">&gt;</span>, Builder, D<span class="op">&gt;</span>;</span>
<span id="cb48-5"><a href="#cb48-5"></a>  Derived<span class="op">&amp;</span> self<span class="op">()</span> <span class="op">{</span></span>
<span id="cb48-6"><a href="#cb48-6"></a>    <span class="cf">return</span> <span class="op">*</span><span class="kw">static_cast</span><span class="op">&lt;</span>Derived<span class="op">*&gt;(</span><span class="kw">this</span><span class="op">)</span>;</span>
<span id="cb48-7"><a href="#cb48-7"></a>  <span class="op">}</span></span>
<span id="cb48-8"><a href="#cb48-8"></a></span>
<span id="cb48-9"><a href="#cb48-9"></a><span class="kw">public</span><span class="op">:</span></span>
<span id="cb48-10"><a href="#cb48-10"></a>  Derived<span class="op">&amp;</span> a<span class="op">()</span> <span class="op">{</span> <span class="co">/* ... */</span>; <span class="cf">return</span> self<span class="op">()</span>; <span class="op">}</span></span>
<span id="cb48-11"><a href="#cb48-11"></a>  Derived<span class="op">&amp;</span> b<span class="op">()</span> <span class="op">{</span> <span class="co">/* ... */</span>; <span class="cf">return</span> self<span class="op">()</span>; <span class="op">}</span></span>
<span id="cb48-12"><a href="#cb48-12"></a>  Derived<span class="op">&amp;</span> c<span class="op">()</span> <span class="op">{</span> <span class="co">/* ... */</span>; <span class="cf">return</span> self<span class="op">()</span>; <span class="op">}</span></span>
<span id="cb48-13"><a href="#cb48-13"></a><span class="op">}</span>;</span>
<span id="cb48-14"><a href="#cb48-14"></a></span>
<span id="cb48-15"><a href="#cb48-15"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> D<span class="op">=</span><span class="dt">void</span><span class="op">&gt;</span></span>
<span id="cb48-16"><a href="#cb48-16"></a><span class="kw">struct</span> Special</span>
<span id="cb48-17"><a href="#cb48-17"></a>  <span class="op">:</span> Builder<span class="op">&lt;</span>conditional_t<span class="op">&lt;</span>is_void_v<span class="op">&lt;</span>D<span class="op">&gt;</span>,Special<span class="op">&lt;</span>D<span class="op">&gt;</span>,D<span class="op">&gt;</span></span>
<span id="cb48-18"><a href="#cb48-18"></a><span class="op">{</span></span>
<span id="cb48-19"><a href="#cb48-19"></a>  <span class="kw">using</span> Derived <span class="op">=</span> <span class="kw">typename</span> Special<span class="op">::</span>Builder<span class="op">::</span>Derived;</span>
<span id="cb48-20"><a href="#cb48-20"></a>  Derived<span class="op">&amp;</span> d<span class="op">()</span> <span class="op">{</span> <span class="co">/* ... */</span>; <span class="cf">return</span> <span class="kw">this</span><span class="op">-&gt;</span>self<span class="op">()</span>; <span class="op">}</span></span>
<span id="cb48-21"><a href="#cb48-21"></a>  Derived<span class="op">&amp;</span> e<span class="op">()</span> <span class="op">{</span> <span class="co">/* ... */</span>; <span class="cf">return</span> <span class="kw">this</span><span class="op">-&gt;</span>self<span class="op">()</span>; <span class="op">}</span></span>
<span id="cb48-22"><a href="#cb48-22"></a><span class="op">}</span>;</span>
<span id="cb48-23"><a href="#cb48-23"></a></span>
<span id="cb48-24"><a href="#cb48-24"></a><span class="kw">struct</span> Super <span class="op">:</span> Special<span class="op">&lt;</span>Super<span class="op">&gt;</span></span>
<span id="cb48-25"><a href="#cb48-25"></a><span class="op">{</span></span>
<span id="cb48-26"><a href="#cb48-26"></a>    Super<span class="op">&amp;</span> f<span class="op">()</span> <span class="op">{</span> <span class="co">/* ... */</span>; <span class="cf">return</span> <span class="op">*</span><span class="kw">this</span>; <span class="op">}</span></span>
<span id="cb48-27"><a href="#cb48-27"></a><span class="op">}</span>;</span>
<span id="cb48-28"><a href="#cb48-28"></a></span>
<span id="cb48-29"><a href="#cb48-29"></a>Builder<span class="op">().</span>a<span class="op">().</span>b<span class="op">().</span>a<span class="op">().</span>b<span class="op">().</span>c<span class="op">()</span>;</span>
<span id="cb48-30"><a href="#cb48-30"></a>Special<span class="op">().</span>a<span class="op">().</span>d<span class="op">().</span>e<span class="op">().</span>a<span class="op">()</span>;</span>
<span id="cb48-31"><a href="#cb48-31"></a>Super<span class="op">().</span>a<span class="op">().</span>d<span class="op">().</span>f<span class="op">().</span>e<span class="op">()</span>;</span></code></pre></div>
</td>
<td>
<div class="sourceCode" id="cb49"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb49-1"><a href="#cb49-1"></a><span class="kw">struct</span> Builder <span class="op">{</span></span>
<span id="cb49-2"><a href="#cb49-2"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> Self<span class="op">&gt;</span></span>
<span id="cb49-3"><a href="#cb49-3"></a>    Self<span class="op">&amp;</span> a<span class="op">(</span><span class="kw">this</span> Self<span class="op">&amp;&amp;</span> self<span class="op">)</span> <span class="op">{</span> <span class="co">/* ... */</span>; <span class="cf">return</span> self; <span class="op">}</span></span>
<span id="cb49-4"><a href="#cb49-4"></a></span>
<span id="cb49-5"><a href="#cb49-5"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> Self<span class="op">&gt;</span></span>
<span id="cb49-6"><a href="#cb49-6"></a>    Self<span class="op">&amp;</span> b<span class="op">(</span><span class="kw">this</span> Self<span class="op">&amp;&amp;</span> self<span class="op">)</span> <span class="op">{</span> <span class="co">/* ... */</span>; <span class="cf">return</span> self; <span class="op">}</span></span>
<span id="cb49-7"><a href="#cb49-7"></a></span>
<span id="cb49-8"><a href="#cb49-8"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> Self<span class="op">&gt;</span></span>
<span id="cb49-9"><a href="#cb49-9"></a>    Self<span class="op">&amp;</span> c<span class="op">(</span><span class="kw">this</span> Self<span class="op">&amp;&amp;</span> self<span class="op">)</span> <span class="op">{</span> <span class="co">/* ... */</span>; <span class="cf">return</span> self; <span class="op">}</span></span>
<span id="cb49-10"><a href="#cb49-10"></a><span class="op">}</span>;</span>
<span id="cb49-11"><a href="#cb49-11"></a></span>
<span id="cb49-12"><a href="#cb49-12"></a><span class="kw">struct</span> Special <span class="op">:</span> Builder <span class="op">{</span></span>
<span id="cb49-13"><a href="#cb49-13"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> Self<span class="op">&gt;</span></span>
<span id="cb49-14"><a href="#cb49-14"></a>    Self<span class="op">&amp;</span> d<span class="op">(</span><span class="kw">this</span> Self<span class="op">&amp;&amp;</span> self<span class="op">)</span> <span class="op">{</span> <span class="co">/* ... */</span>; <span class="cf">return</span> self; <span class="op">}</span></span>
<span id="cb49-15"><a href="#cb49-15"></a></span>
<span id="cb49-16"><a href="#cb49-16"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> Self<span class="op">&gt;</span></span>
<span id="cb49-17"><a href="#cb49-17"></a>    Self<span class="op">&amp;</span> e<span class="op">(</span><span class="kw">this</span> Self<span class="op">&amp;&amp;</span> self<span class="op">)</span> <span class="op">{</span> <span class="co">/* ... */</span>; <span class="cf">return</span> self; <span class="op">}</span></span>
<span id="cb49-18"><a href="#cb49-18"></a><span class="op">}</span>;</span>
<span id="cb49-19"><a href="#cb49-19"></a></span>
<span id="cb49-20"><a href="#cb49-20"></a><span class="kw">struct</span> Super <span class="op">:</span> Special <span class="op">{</span></span>
<span id="cb49-21"><a href="#cb49-21"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> Self<span class="op">&gt;</span></span>
<span id="cb49-22"><a href="#cb49-22"></a>    Self<span class="op">&amp;</span> f<span class="op">(</span><span class="kw">this</span> Self<span class="op">&amp;&amp;</span> self<span class="op">)</span> <span class="op">{</span> <span class="co">/* ... */</span>; <span class="cf">return</span> self; <span class="op">}</span></span>
<span id="cb49-23"><a href="#cb49-23"></a><span class="op">}</span>;</span>
<span id="cb49-24"><a href="#cb49-24"></a></span>
<span id="cb49-25"><a href="#cb49-25"></a>Builder<span class="op">().</span>a<span class="op">().</span>b<span class="op">().</span>a<span class="op">().</span>b<span class="op">().</span>c<span class="op">()</span>;</span>
<span id="cb49-26"><a href="#cb49-26"></a>Special<span class="op">().</span>a<span class="op">().</span>d<span class="op">().</span>e<span class="op">().</span>a<span class="op">()</span>;</span>
<span id="cb49-27"><a href="#cb49-27"></a>Super<span class="op">().</span>a<span class="op">().</span>d<span class="op">().</span>f<span class="op">().</span>e<span class="op">()</span>;</span></code></pre></div>
</td>
</tr>
</table>
<p>The code on the right is much easier in all contexts. There are so many situations where this idiom, if available, would give programmers a better solution for problems that they cannot easily solve today.</p>
<p>Note that the <code class="sourceCode cpp">Super</code> implementations with this proposal opt-in to further derivation, since it’s a no-brainer at this point.</p>
<h2 data-number="5.3" id="recursive-lambdas"><span class="header-section-number">5.3</span> Recursive Lambdas<a href="#recursive-lambdas" class="self-link"></a></h2>
<p>The explicit object parameter syntax offers an alternative solution to implementing a recursive lambda as compared to <span class="citation" data-cites="P0839R0">[<a href="#ref-P0839R0" role="doc-biblioref">P0839R0</a>]</span>, since now we’ve opened up the possibility of allowing a lambda to reference itself. To do this, we need a way to <em>name</em> the lambda.</p>
<div class="sourceCode" id="cb50"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb50-1"><a href="#cb50-1"></a><span class="co">// as proposed in P0839</span></span>
<span id="cb50-2"><a href="#cb50-2"></a><span class="kw">auto</span> fib <span class="op">=</span> <span class="op">[]</span> self <span class="op">(</span><span class="dt">int</span> n<span class="op">)</span> <span class="op">{</span></span>
<span id="cb50-3"><a href="#cb50-3"></a>    <span class="cf">if</span> <span class="op">(</span>n <span class="op">&lt;</span> <span class="dv">2</span><span class="op">)</span> <span class="cf">return</span> n;</span>
<span id="cb50-4"><a href="#cb50-4"></a>    <span class="cf">return</span> self<span class="op">(</span>n<span class="op">-</span><span class="dv">1</span><span class="op">)</span> <span class="op">+</span> self<span class="op">(</span>n<span class="op">-</span><span class="dv">2</span><span class="op">)</span>;</span>
<span id="cb50-5"><a href="#cb50-5"></a><span class="op">}</span>;</span>
<span id="cb50-6"><a href="#cb50-6"></a></span>
<span id="cb50-7"><a href="#cb50-7"></a><span class="co">// this proposal</span></span>
<span id="cb50-8"><a href="#cb50-8"></a><span class="kw">auto</span> fib <span class="op">=</span> <span class="op">[](</span><span class="kw">this</span> <span class="kw">auto</span> self, <span class="dt">int</span> n<span class="op">)</span> <span class="op">{</span></span>
<span id="cb50-9"><a href="#cb50-9"></a>    <span class="cf">if</span> <span class="op">(</span>n <span class="op">&lt;</span> <span class="dv">2</span><span class="op">)</span> <span class="cf">return</span> n;</span>
<span id="cb50-10"><a href="#cb50-10"></a>    <span class="cf">return</span> self<span class="op">(</span>n<span class="op">-</span><span class="dv">1</span><span class="op">)</span> <span class="op">+</span> self<span class="op">(</span>n<span class="op">-</span><span class="dv">2</span><span class="op">)</span>;</span>
<span id="cb50-11"><a href="#cb50-11"></a><span class="op">}</span>;</span></code></pre></div>
<p>This works by following the established rules. The call operator of the closure object can also have an explicit object parameter, so in this example, <code class="sourceCode cpp">self</code> is the closure object.</p>
<p>In San Diego, issues of implementability were raised. The proposal ends up being implementable. See <a href="#faq-rec-lambda-impl">the lambda FAQ entry</a> for details.</p>
<p>Combine this with the new style of mixins allowing us to automatically deduce the most derived object, and you get the following example — a simple recursive lambda that counts the number of leaves in a tree.</p>
<div class="sourceCode" id="cb51"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb51-1"><a href="#cb51-1"></a><span class="kw">struct</span> Leaf <span class="op">{</span> <span class="op">}</span>;</span>
<span id="cb51-2"><a href="#cb51-2"></a><span class="kw">struct</span> Node;</span>
<span id="cb51-3"><a href="#cb51-3"></a><span class="kw">using</span> Tree <span class="op">=</span> variant<span class="op">&lt;</span>Leaf, Node<span class="op">*&gt;</span>;</span>
<span id="cb51-4"><a href="#cb51-4"></a><span class="kw">struct</span> Node <span class="op">{</span></span>
<span id="cb51-5"><a href="#cb51-5"></a>    Tree left;</span>
<span id="cb51-6"><a href="#cb51-6"></a>    Tree right;</span>
<span id="cb51-7"><a href="#cb51-7"></a><span class="op">}</span>;</span>
<span id="cb51-8"><a href="#cb51-8"></a></span>
<span id="cb51-9"><a href="#cb51-9"></a><span class="dt">int</span> num_leaves<span class="op">(</span>Tree <span class="kw">const</span><span class="op">&amp;</span> tree<span class="op">)</span> <span class="op">{</span></span>
<span id="cb51-10"><a href="#cb51-10"></a>    <span class="cf">return</span> visit<span class="op">(</span>overload<span class="op">(</span>        <span class="co">// &lt;-----------------------------------+</span></span>
<span id="cb51-11"><a href="#cb51-11"></a>        <span class="op">[](</span>Leaf <span class="kw">const</span><span class="op">&amp;)</span> <span class="op">{</span> <span class="cf">return</span> <span class="dv">1</span>; <span class="op">}</span>,                           <span class="co">//      |</span></span>
<span id="cb51-12"><a href="#cb51-12"></a>        <span class="op">[](</span><span class="kw">this</span> <span class="kw">auto</span> <span class="kw">const</span><span class="op">&amp;</span> self, Node<span class="op">*</span> n<span class="op">)</span> <span class="op">-&gt;</span> <span class="dt">int</span> <span class="op">{</span>              <span class="co">//      |</span></span>
<span id="cb51-13"><a href="#cb51-13"></a>            <span class="cf">return</span> visit<span class="op">(</span>self, n<span class="op">-&gt;</span>left<span class="op">)</span> <span class="op">+</span> visit<span class="op">(</span>self, n<span class="op">-&gt;</span>right<span class="op">)</span>; <span class="co">// &lt;----+</span></span>
<span id="cb51-14"><a href="#cb51-14"></a>        <span class="op">}</span></span>
<span id="cb51-15"><a href="#cb51-15"></a>    <span class="op">)</span>, tree<span class="op">)</span>;</span>
<span id="cb51-16"><a href="#cb51-16"></a><span class="op">}</span></span></code></pre></div>
<p>In the calls to <code class="sourceCode cpp">visit</code>, <code class="sourceCode cpp">self</code> isn’t the lambda; <code class="sourceCode cpp">self</code> is the <code class="sourceCode cpp">overload</code> wrapper. This works straight out of the box.</p>
<h2 data-number="5.4" id="by-value-member-functions"><span class="header-section-number">5.4</span> By-value member functions<a href="#by-value-member-functions" class="self-link"></a></h2>
<p>This section presents some of the cases for by-value member functions.</p>
<h3 data-number="5.4.1" id="move-into-parameter"><span class="header-section-number">5.4.1</span> For move-into-parameter chaining<a href="#move-into-parameter" class="self-link"></a></h3>
<p>Say you wanted to provide a <code class="sourceCode cpp"><span class="op">.</span>sorted<span class="op">()</span></code> method on a data structure. Such a method naturally wants to operate on a copy. Taking the parameter by value will cleanly and correctly move into the parameter if the original object is an rvalue without requiring templates.</p>
<div class="sourceCode" id="cb52"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb52-1"><a href="#cb52-1"></a><span class="kw">struct</span> my_vector <span class="op">:</span> vector<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb52-2"><a href="#cb52-2"></a>  <span class="kw">auto</span> sorted<span class="op">(</span><span class="kw">this</span> my_vector self<span class="op">)</span> <span class="op">-&gt;</span> my_vector <span class="op">{</span></span>
<span id="cb52-3"><a href="#cb52-3"></a>    sort<span class="op">(</span>self<span class="op">.</span>begin<span class="op">()</span>, self<span class="op">.</span>end<span class="op">())</span>;</span>
<span id="cb52-4"><a href="#cb52-4"></a>    <span class="cf">return</span> self;</span>
<span id="cb52-5"><a href="#cb52-5"></a>  <span class="op">}</span></span>
<span id="cb52-6"><a href="#cb52-6"></a><span class="op">}</span>;</span></code></pre></div>
<h3 data-number="5.4.2" id="by-value-member-functions-for-performance"><span class="header-section-number">5.4.2</span> For performance<a href="#by-value-member-functions-for-performance" class="self-link"></a></h3>
<p>It’s been established that if you want the best performance, you should pass small types by value to avoid an indirection penalty. One such small type is <code class="sourceCode cpp">std<span class="op">::</span>string_view</code>. <a href="https://abseil.io/tips/1">Abseil Tip #1</a> for instance, states:</p>
<blockquote>
<p>Unlike other string types, you should pass <code class="sourceCode cpp">string_view</code> by value just like you would an <code class="sourceCode cpp"><span class="dt">int</span></code> or a <code class="sourceCode cpp"><span class="dt">double</span></code> because <code class="sourceCode cpp">string_view</code> is a small value.</p>
</blockquote>
<p>There is, however, one place today where you simply <em>cannot</em> pass types like <code class="sourceCode cpp">string_view</code> by value: to their own member functions. The implicit object parameter is always a reference, so any such member functions that do not get inlined incur a double indirection.</p>
<p>As an easy performance optimization, any member function of small types that does not perform any modifications can take the object parameter by value. Here is an example of some member functions of <code class="sourceCode cpp">basic_string_view</code> assuming that we are just using <code class="sourceCode cpp">charT <span class="kw">const</span><span class="op">*</span></code> as <code class="sourceCode cpp">iterator</code>:</p>
<div class="sourceCode" id="cb53"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb53-1"><a href="#cb53-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> charT, <span class="kw">class</span> traits <span class="op">=</span> char_traits<span class="op">&lt;</span>charT<span class="op">&gt;&gt;</span></span>
<span id="cb53-2"><a href="#cb53-2"></a><span class="kw">class</span> basic_string_view <span class="op">{</span></span>
<span id="cb53-3"><a href="#cb53-3"></a><span class="kw">private</span><span class="op">:</span></span>
<span id="cb53-4"><a href="#cb53-4"></a>    const_pointer data_;</span>
<span id="cb53-5"><a href="#cb53-5"></a>    size_type size_;</span>
<span id="cb53-6"><a href="#cb53-6"></a><span class="kw">public</span><span class="op">:</span></span>
<span id="cb53-7"><a href="#cb53-7"></a>    <span class="kw">constexpr</span> const_iterator begin<span class="op">(</span><span class="kw">this</span> basic_string_view self<span class="op">)</span> <span class="op">{</span></span>
<span id="cb53-8"><a href="#cb53-8"></a>        <span class="cf">return</span> self<span class="op">.</span>data_;</span>
<span id="cb53-9"><a href="#cb53-9"></a>    <span class="op">}</span></span>
<span id="cb53-10"><a href="#cb53-10"></a></span>
<span id="cb53-11"><a href="#cb53-11"></a>    <span class="kw">constexpr</span> const_iterator end<span class="op">(</span><span class="kw">this</span> basic_string_view self<span class="op">)</span> <span class="op">{</span></span>
<span id="cb53-12"><a href="#cb53-12"></a>        <span class="cf">return</span> self<span class="op">.</span>data_ <span class="op">+</span> self<span class="op">.</span>size_;</span>
<span id="cb53-13"><a href="#cb53-13"></a>    <span class="op">}</span></span>
<span id="cb53-14"><a href="#cb53-14"></a></span>
<span id="cb53-15"><a href="#cb53-15"></a>    <span class="kw">constexpr</span> <span class="dt">size_t</span> size<span class="op">(</span><span class="kw">this</span> basic_string_view self<span class="op">)</span> <span class="op">{</span></span>
<span id="cb53-16"><a href="#cb53-16"></a>        <span class="cf">return</span> self<span class="op">.</span>size_;</span>
<span id="cb53-17"><a href="#cb53-17"></a>    <span class="op">}</span></span>
<span id="cb53-18"><a href="#cb53-18"></a></span>
<span id="cb53-19"><a href="#cb53-19"></a>    <span class="kw">constexpr</span> const_reference <span class="kw">operator</span><span class="op">[](</span><span class="kw">this</span> basic_string_view self, size_type pos<span class="op">)</span> <span class="op">{</span></span>
<span id="cb53-20"><a href="#cb53-20"></a>        <span class="cf">return</span> self<span class="op">.</span>data_<span class="op">[</span>pos<span class="op">]</span>;</span>
<span id="cb53-21"><a href="#cb53-21"></a>    <span class="op">}</span></span>
<span id="cb53-22"><a href="#cb53-22"></a><span class="op">}</span>;</span></code></pre></div>
<p>Most of the member functions can be rewritten this way for a free performance boost.</p>
<p>The same can be said for types that aren’t only cheap to copy, but have no state at all. Compare these two implementations of <code class="sourceCode cpp">less_than</code>:</p>
<table style="width:100%">
<tr>
<th style="width:50%">
C++17
</th>
<th style="width:50%">
Proposed
</th>
</tr>
<tr>
<td>
<div class="sourceCode" id="cb54"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb54-1"><a href="#cb54-1"></a><span class="kw">struct</span> less_than <span class="op">{</span></span>
<span id="cb54-2"><a href="#cb54-2"></a>  <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T, <span class="kw">typename</span> U<span class="op">&gt;</span></span>
<span id="cb54-3"><a href="#cb54-3"></a>  <span class="dt">bool</span> <span class="kw">operator</span><span class="op">()(</span>T <span class="kw">const</span><span class="op">&amp;</span> lhs, U <span class="kw">const</span><span class="op">&amp;</span> rhs<span class="op">)</span> <span class="op">{</span></span>
<span id="cb54-4"><a href="#cb54-4"></a>    <span class="cf">return</span> lhs <span class="op">&lt;</span> rhs;</span>
<span id="cb54-5"><a href="#cb54-5"></a>  <span class="op">}</span></span>
<span id="cb54-6"><a href="#cb54-6"></a><span class="op">}</span>;</span></code></pre></div>
</td>
<td>
<div class="sourceCode" id="cb55"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb55-1"><a href="#cb55-1"></a><span class="kw">struct</span> less_than <span class="op">{</span></span>
<span id="cb55-2"><a href="#cb55-2"></a>  <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T, <span class="kw">typename</span> U<span class="op">&gt;</span></span>
<span id="cb55-3"><a href="#cb55-3"></a>  <span class="dt">bool</span> <span class="kw">operator</span><span class="op">()(</span><span class="kw">this</span> less_than,</span>
<span id="cb55-4"><a href="#cb55-4"></a>          T <span class="kw">const</span><span class="op">&amp;</span> lhs, U <span class="kw">const</span><span class="op">&amp;</span> rhs<span class="op">)</span> <span class="op">{</span></span>
<span id="cb55-5"><a href="#cb55-5"></a>    <span class="cf">return</span> lhs <span class="op">&lt;</span> rhs;</span>
<span id="cb55-6"><a href="#cb55-6"></a>  <span class="op">}</span></span>
<span id="cb55-7"><a href="#cb55-7"></a><span class="op">}</span>;</span></code></pre></div>
</td>
</tr>
</table>
<p>In C++17, invoking <code class="sourceCode cpp">less_than<span class="op">()(</span>x, y<span class="op">)</span></code> still requires an implicit reference to the <code class="sourceCode cpp">less_than</code> object — completely unnecessary work when copying it is free. The compiler knows it doesn’t have to do anything. We <em>want</em> to pass <code class="sourceCode cpp">less_than</code> by value here. Indeed, this specific situation is the main motivation for <span class="citation" data-cites="P1169R0">[<a href="#ref-P1169R0" role="doc-biblioref">P1169R0</a>]</span>.</p>
<h3 data-number="5.4.3" id="for-lifetime-management-of-coroutines"><span class="header-section-number">5.4.3</span> For lifetime management of coroutines<a href="#for-lifetime-management-of-coroutines" class="self-link"></a></h3>
<p>One issue with coroutines is dealing with dangling references. This issue isn’t specific to coroutines at all, it’s simply that coroutines provide another venue for dangling references that takes some adjusting to.</p>
<p>One way to avoid dealing with dangling references is to, quite simply, not have references:</p>
<table style="width:100%">
<tr>
<th style="width:50%">
Dangles
</th>
<th style="width:50%">
Doesn’t dangle
</th>
</tr>
<tr>
<td>
<div class="sourceCode" id="cb56"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb56-1"><a href="#cb56-1"></a><span class="kw">auto</span> always<span class="op">(</span><span class="dt">int</span> <span class="kw">const</span><span class="op">&amp;</span> val<span class="op">)</span> <span class="op">-&gt;</span> std<span class="op">::</span>generator<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb56-2"><a href="#cb56-2"></a>    <span class="cf">for</span> <span class="op">(</span>;;<span class="op">)</span> <span class="op">{</span></span>
<span id="cb56-3"><a href="#cb56-3"></a>        <span class="kw">co_yield</span> val;</span>
<span id="cb56-4"><a href="#cb56-4"></a>    <span class="op">}</span></span>
<span id="cb56-5"><a href="#cb56-5"></a><span class="op">}</span></span>
<span id="cb56-6"><a href="#cb56-6"></a></span>
<span id="cb56-7"><a href="#cb56-7"></a><span class="co">// &#39;val&#39; above ends up being a dangling reference</span></span>
<span id="cb56-8"><a href="#cb56-8"></a><span class="cf">for</span> <span class="op">(</span><span class="dt">int</span> i <span class="op">:</span> always<span class="op">(</span><span class="dv">42</span><span class="op">))</span> <span class="op">{</span> <span class="op">...</span> <span class="op">}</span></span></code></pre></div>
</td>
<td>
<div class="sourceCode" id="cb57"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb57-1"><a href="#cb57-1"></a><span class="kw">auto</span> always<span class="op">(</span><span class="dt">int</span> val<span class="op">)</span> <span class="op">-&gt;</span> std<span class="op">::</span>generator<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb57-2"><a href="#cb57-2"></a>    <span class="cf">for</span> <span class="op">(</span>;;<span class="op">)</span> <span class="op">{</span></span>
<span id="cb57-3"><a href="#cb57-3"></a>        <span class="kw">co_yield</span> val;</span>
<span id="cb57-4"><a href="#cb57-4"></a>    <span class="op">}</span></span>
<span id="cb57-5"><a href="#cb57-5"></a><span class="op">}</span></span>
<span id="cb57-6"><a href="#cb57-6"></a></span>
<span id="cb57-7"><a href="#cb57-7"></a><span class="co">// ok: val is copied</span></span>
<span id="cb57-8"><a href="#cb57-8"></a><span class="cf">for</span> <span class="op">(</span><span class="dt">int</span> i <span class="op">:</span> always<span class="op">(</span><span class="dv">42</span><span class="op">))</span> <span class="op">{</span> <span class="op">...</span> <span class="op">}</span></span></code></pre></div>
</td>
</tr>
</table>
<p>This general approach works for every function parameter — except the implicit object parameter, which is always a reference. But this proposal allows you to to avoid this dangling even for member function coroutines by also taking the object parameter by value:</p>
<table style="width:100%">
<tr>
<th style="width:50%">
Dangles
</th>
<th style="width:50%">
Doesn’t dangle
</th>
</tr>
<tr>
<td>
<div class="sourceCode" id="cb58"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb58-1"><a href="#cb58-1"></a><span class="kw">struct</span> C <span class="op">{</span></span>
<span id="cb58-2"><a href="#cb58-2"></a>    <span class="dt">int</span> val;</span>
<span id="cb58-3"><a href="#cb58-3"></a>    </span>
<span id="cb58-4"><a href="#cb58-4"></a>    <span class="kw">auto</span> always<span class="op">()</span> <span class="kw">const</span> <span class="op">-&gt;</span> std<span class="op">::</span>generator<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb58-5"><a href="#cb58-5"></a>        <span class="cf">for</span> <span class="op">(</span>;;<span class="op">)</span> <span class="op">{</span></span>
<span id="cb58-6"><a href="#cb58-6"></a>            <span class="kw">co_yield</span> val;</span>
<span id="cb58-7"><a href="#cb58-7"></a>        <span class="op">}</span></span>
<span id="cb58-8"><a href="#cb58-8"></a>    <span class="op">}</span></span>
<span id="cb58-9"><a href="#cb58-9"></a><span class="op">}</span>;</span>
<span id="cb58-10"><a href="#cb58-10"></a></span>
<span id="cb58-11"><a href="#cb58-11"></a><span class="co">// &#39;this&#39; above ends up being a dangling pointer</span></span>
<span id="cb58-12"><a href="#cb58-12"></a><span class="cf">for</span> <span class="op">(</span><span class="dt">int</span> i <span class="op">:</span> C<span class="op">{</span><span class="dv">42</span><span class="op">}.</span>always<span class="op">())</span> <span class="op">{</span> <span class="op">...</span> <span class="op">}</span></span></code></pre></div>
</td>
<td>
<div class="sourceCode" id="cb59"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb59-1"><a href="#cb59-1"></a><span class="kw">struct</span> C <span class="op">{</span></span>
<span id="cb59-2"><a href="#cb59-2"></a>    <span class="dt">int</span> val;</span>
<span id="cb59-3"><a href="#cb59-3"></a>    </span>
<span id="cb59-4"><a href="#cb59-4"></a>    <span class="kw">auto</span> always<span class="op">(</span><span class="kw">this</span> C c<span class="op">)</span> <span class="op">-&gt;</span> std<span class="op">::</span>generator<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb59-5"><a href="#cb59-5"></a>        <span class="cf">for</span> <span class="op">(</span>;;<span class="op">)</span> <span class="op">{</span></span>
<span id="cb59-6"><a href="#cb59-6"></a>            <span class="kw">co_yield</span> c<span class="op">.</span>val;</span>
<span id="cb59-7"><a href="#cb59-7"></a>        <span class="op">}</span></span>
<span id="cb59-8"><a href="#cb59-8"></a>    <span class="op">}</span></span>
<span id="cb59-9"><a href="#cb59-9"></a><span class="op">}</span>;</span>
<span id="cb59-10"><a href="#cb59-10"></a></span>
<span id="cb59-11"><a href="#cb59-11"></a><span class="co">// ok: C is copied</span></span>
<span id="cb59-12"><a href="#cb59-12"></a><span class="cf">for</span> <span class="op">(</span><span class="dt">int</span> i <span class="op">:</span> C<span class="op">{</span><span class="dv">42</span><span class="op">}.</span>always<span class="op">())</span> <span class="op">{</span> <span class="op">...</span> <span class="op">}</span></span></code></pre></div>
</td>
</tr>
</table>
<h2 data-number="5.5" id="sfinae-friendly-callables"><span class="header-section-number">5.5</span> SFINAE-friendly callables<a href="#sfinae-friendly-callables" class="self-link"></a></h2>
<p>A seemingly unrelated problem to the question of code quadruplication is that of writing numerous overloads for function wrappers, as demonstrated in <span class="citation" data-cites="P0826R0">[<a href="#ref-P0826R0" role="doc-biblioref">P0826R0</a>]</span>. Consider what happens if we implement <code class="sourceCode cpp">std<span class="op">::</span>not_fn<span class="op">()</span></code> as currently specified:</p>
<div class="sourceCode" id="cb60"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb60-1"><a href="#cb60-1"></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="cb60-2"><a href="#cb60-2"></a><span class="kw">class</span> call_wrapper <span class="op">{</span></span>
<span id="cb60-3"><a href="#cb60-3"></a>    F f;</span>
<span id="cb60-4"><a href="#cb60-4"></a><span class="kw">public</span><span class="op">:</span></span>
<span id="cb60-5"><a href="#cb60-5"></a>    <span class="co">// ...</span></span>
<span id="cb60-6"><a href="#cb60-6"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span><span class="op">...</span> Args<span class="op">&gt;</span></span>
<span id="cb60-7"><a href="#cb60-7"></a>    <span class="kw">auto</span> <span class="kw">operator</span><span class="op">()(</span>Args<span class="op">&amp;&amp;...</span> <span class="op">)</span> <span class="op">&amp;</span></span>
<span id="cb60-8"><a href="#cb60-8"></a>        <span class="op">-&gt;</span> <span class="kw">decltype</span><span class="op">(!</span>declval<span class="op">&lt;</span>invoke_result_t<span class="op">&lt;</span>F<span class="op">&amp;</span>, Args<span class="op">...&gt;&gt;())</span>;</span>
<span id="cb60-9"><a href="#cb60-9"></a></span>
<span id="cb60-10"><a href="#cb60-10"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span><span class="op">...</span> Args<span class="op">&gt;</span></span>
<span id="cb60-11"><a href="#cb60-11"></a>    <span class="kw">auto</span> <span class="kw">operator</span><span class="op">()(</span>Args<span class="op">&amp;&amp;...</span> <span class="op">)</span> <span class="kw">const</span><span class="op">&amp;</span></span>
<span id="cb60-12"><a href="#cb60-12"></a>        <span class="op">-&gt;</span> <span class="kw">decltype</span><span class="op">(!</span>declval<span class="op">&lt;</span>invoke_result_t<span class="op">&lt;</span>F <span class="kw">const</span><span class="op">&amp;</span>, Args<span class="op">...&gt;&gt;())</span>;</span>
<span id="cb60-13"><a href="#cb60-13"></a></span>
<span id="cb60-14"><a href="#cb60-14"></a>    <span class="co">// ... same for &amp;&amp; and const &amp;&amp; ...</span></span>
<span id="cb60-15"><a href="#cb60-15"></a><span class="op">}</span>;</span>
<span id="cb60-16"><a href="#cb60-16"></a></span>
<span id="cb60-17"><a href="#cb60-17"></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="cb60-18"><a href="#cb60-18"></a><span class="kw">auto</span> not_fn<span class="op">(</span>F<span class="op">&amp;&amp;</span> f<span class="op">)</span> <span class="op">{</span></span>
<span id="cb60-19"><a href="#cb60-19"></a>    <span class="cf">return</span> call_wrapper<span class="op">&lt;</span>decay_t<span class="op">&lt;</span>F<span class="op">&gt;&gt;{</span>forward<span class="op">&lt;</span>F<span class="op">&gt;(</span>f<span class="op">)}</span>;</span>
<span id="cb60-20"><a href="#cb60-20"></a><span class="op">}</span></span></code></pre></div>
<p>As described in the paper, this implementation has two pathological cases: one in which the callable is SFINAE-unfriendly, causing the call to be ill-formed where it would otherwise work; and one in which overload is deleted, causing the call to fall back to a different overload when it should fail instead:</p>
<div class="sourceCode" id="cb61"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb61-1"><a href="#cb61-1"></a><span class="kw">struct</span> unfriendly <span class="op">{</span></span>
<span id="cb61-2"><a href="#cb61-2"></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="cb61-3"><a href="#cb61-3"></a>    <span class="kw">auto</span> <span class="kw">operator</span><span class="op">()(</span>T v<span class="op">)</span> <span class="op">{</span></span>
<span id="cb61-4"><a href="#cb61-4"></a>        <span class="kw">static_assert</span><span class="op">(</span>is_same_v<span class="op">&lt;</span>T, <span class="dt">int</span><span class="op">&gt;)</span>;</span>
<span id="cb61-5"><a href="#cb61-5"></a>        <span class="cf">return</span> v;</span>
<span id="cb61-6"><a href="#cb61-6"></a>    <span class="op">}</span></span>
<span id="cb61-7"><a href="#cb61-7"></a></span>
<span id="cb61-8"><a href="#cb61-8"></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="cb61-9"><a href="#cb61-9"></a>    <span class="kw">auto</span> <span class="kw">operator</span><span class="op">()(</span>T v<span class="op">)</span> <span class="kw">const</span> <span class="op">{</span></span>
<span id="cb61-10"><a href="#cb61-10"></a>        <span class="kw">static_assert</span><span class="op">(</span>is_same_v<span class="op">&lt;</span>T, <span class="dt">double</span><span class="op">&gt;)</span>;</span>
<span id="cb61-11"><a href="#cb61-11"></a>        <span class="cf">return</span> v;</span>
<span id="cb61-12"><a href="#cb61-12"></a>    <span class="op">}</span></span>
<span id="cb61-13"><a href="#cb61-13"></a><span class="op">}</span>;</span>
<span id="cb61-14"><a href="#cb61-14"></a></span>
<span id="cb61-15"><a href="#cb61-15"></a><span class="kw">struct</span> fun <span class="op">{</span></span>
<span id="cb61-16"><a href="#cb61-16"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span><span class="op">...</span> Args<span class="op">&gt;</span></span>
<span id="cb61-17"><a href="#cb61-17"></a>    <span class="dt">void</span> <span class="kw">operator</span><span class="op">()(</span>Args<span class="op">&amp;&amp;...)</span> <span class="op">=</span> <span class="kw">delete</span>;</span>
<span id="cb61-18"><a href="#cb61-18"></a></span>
<span id="cb61-19"><a href="#cb61-19"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span><span class="op">...</span> Args<span class="op">&gt;</span></span>
<span id="cb61-20"><a href="#cb61-20"></a>    <span class="dt">bool</span> <span class="kw">operator</span><span class="op">()(</span>Args<span class="op">&amp;&amp;...)</span> <span class="kw">const</span> <span class="op">{</span> <span class="cf">return</span> <span class="kw">true</span>; <span class="op">}</span></span>
<span id="cb61-21"><a href="#cb61-21"></a><span class="op">}</span>;</span>
<span id="cb61-22"><a href="#cb61-22"></a></span>
<span id="cb61-23"><a href="#cb61-23"></a>std<span class="op">::</span>not_fn<span class="op">(</span>unfriendly<span class="op">{})(</span><span class="dv">1</span><span class="op">)</span>; <span class="co">// static assert!</span></span>
<span id="cb61-24"><a href="#cb61-24"></a>                              <span class="co">// even though the non-const overload is viable and would be the</span></span>
<span id="cb61-25"><a href="#cb61-25"></a>                              <span class="co">// best match, during overload resolution, both overloads of</span></span>
<span id="cb61-26"><a href="#cb61-26"></a>                              <span class="co">// unfriendly have to be instantiated - and the second one is a</span></span>
<span id="cb61-27"><a href="#cb61-27"></a>                              <span class="co">// hard compile error.</span></span>
<span id="cb61-28"><a href="#cb61-28"></a></span>
<span id="cb61-29"><a href="#cb61-29"></a>std<span class="op">::</span>not_fn<span class="op">(</span>fun<span class="op">{})()</span>;         <span class="co">// ok!? Returns false</span></span>
<span id="cb61-30"><a href="#cb61-30"></a>                              <span class="co">// even though we want the non-const overload to be deleted, the</span></span>
<span id="cb61-31"><a href="#cb61-31"></a>                              <span class="co">// const overload of the call_wrapper ends up being viable - and</span></span>
<span id="cb61-32"><a href="#cb61-32"></a>                              <span class="co">// the only viable candidate.</span></span></code></pre></div>
<p>Gracefully handling SFINAE-unfriendly callables is <strong>not solvable</strong> in C++ today. Preventing fallback can be solved by the addition of another four overloads, so that each of the four <em>cv</em>/ref-qualifiers leads to a pair of overloads: one enabled and one <code class="sourceCode cpp">deleted</code>.</p>
<p>This proposal solves both problems by allowing <code class="sourceCode cpp"><span class="kw">this</span></code> to be deduced. The following is a complete implementation of <code class="sourceCode cpp">std<span class="op">::</span>not_fn</code>. For simplicity, it makes use of <code class="sourceCode cpp">BOOST_HOF_RETURNS</code> from <a href="https://www.boost.org/doc/libs/1_68_0/libs/hof/doc/html/include/boost/hof/returns.html">Boost.HOF</a> to avoid duplicating expressions:</p>
<div class="sourceCode" id="cb62"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb62-1"><a href="#cb62-1"></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="cb62-2"><a href="#cb62-2"></a><span class="kw">struct</span> call_wrapper <span class="op">{</span></span>
<span id="cb62-3"><a href="#cb62-3"></a>  F f;</span>
<span id="cb62-4"><a href="#cb62-4"></a></span>
<span id="cb62-5"><a href="#cb62-5"></a>  <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> Self, <span class="kw">typename</span><span class="op">...</span> Args<span class="op">&gt;</span></span>
<span id="cb62-6"><a href="#cb62-6"></a>  <span class="kw">auto</span> <span class="kw">operator</span><span class="op">()(</span><span class="kw">this</span> Self<span class="op">&amp;&amp;</span> self, Args<span class="op">&amp;&amp;...</span> args<span class="op">)</span></span>
<span id="cb62-7"><a href="#cb62-7"></a>    BOOST_HOF_RETURNS<span class="op">(</span></span>
<span id="cb62-8"><a href="#cb62-8"></a>      <span class="op">!</span>invoke<span class="op">(</span></span>
<span id="cb62-9"><a href="#cb62-9"></a>        forward<span class="op">&lt;</span>Self<span class="op">&gt;(</span>self<span class="op">).</span>f,</span>
<span id="cb62-10"><a href="#cb62-10"></a>        forward<span class="op">&lt;</span>Args<span class="op">&gt;(</span>args<span class="op">)...))</span></span>
<span id="cb62-11"><a href="#cb62-11"></a><span class="op">}</span>;</span>
<span id="cb62-12"><a href="#cb62-12"></a></span>
<span id="cb62-13"><a href="#cb62-13"></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="cb62-14"><a href="#cb62-14"></a><span class="kw">auto</span> not_fn<span class="op">(</span>F<span class="op">&amp;&amp;</span> f<span class="op">)</span> <span class="op">{</span></span>
<span id="cb62-15"><a href="#cb62-15"></a>  <span class="cf">return</span> call_wrapper<span class="op">&lt;</span>decay_t<span class="op">&lt;</span>F<span class="op">&gt;&gt;{</span>forward<span class="op">&lt;</span>F<span class="op">&gt;(</span>f<span class="op">)}</span>;</span>
<span id="cb62-16"><a href="#cb62-16"></a><span class="op">}</span></span></code></pre></div>
<p>Which leads to:</p>
<div class="sourceCode" id="cb63"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb63-1"><a href="#cb63-1"></a>not_fn<span class="op">(</span>unfriendly<span class="op">{})(</span><span class="dv">1</span><span class="op">)</span>; <span class="co">// ok</span></span>
<span id="cb63-2"><a href="#cb63-2"></a>not_fn<span class="op">(</span>fun<span class="op">{})()</span>;         <span class="co">// error</span></span></code></pre></div>
<p>Here, there is only one overload with everything deduced together. The first example now works correctly. <code class="sourceCode cpp">Self</code> gets deduced as <code class="sourceCode cpp">call_wrapper<span class="op">&lt;</span>unfriendly<span class="op">&gt;</span></code>, and the one <code class="sourceCode cpp"><span class="kw">operator</span><span class="op">()</span></code> will only consider <code class="sourceCode cpp">unfriendly</code>’s non-<code class="sourceCode cpp"><span class="kw">const</span></code> call operator. The <code class="sourceCode cpp"><span class="kw">const</span></code> one is never even considered, so it does not have an opportunity to cause problems.</p>
<p>The second example now also fails correctly. Previously, we had four candidates. The two non-<code class="sourceCode cpp"><span class="kw">const</span></code> options were removed from the overload set due to <code class="sourceCode cpp">fun</code>’s non-<code class="sourceCode cpp"><span class="kw">const</span></code> call operator being <code class="sourceCode cpp"><span class="kw">delete</span></code>d, and the two <code class="sourceCode cpp"><span class="kw">const</span></code> ones which were viable. But now, we only have one candidate. <code class="sourceCode cpp">Self</code> is deduced as <code class="sourceCode cpp">call_wrapper<span class="op">&lt;</span>fun<span class="op">&gt;</span></code>, which requires <code class="sourceCode cpp">fun</code>’s non-<code class="sourceCode cpp"><span class="kw">const</span></code> call operator to be well-formed. Since it is not, the call results in an error. There is no opportunity for fallback since only one overload is ever considered.</p>
<p>This singular overload has precisely the desired behavior: working for <code class="sourceCode cpp">unfriendly</code>, and not working for <code class="sourceCode cpp">fun</code>.</p>
<p>This could also be implemented as a lambda completely within the body of <code class="sourceCode cpp">not_fn</code>:</p>
<div class="sourceCode" id="cb64"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb64-1"><a href="#cb64-1"></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="cb64-2"><a href="#cb64-2"></a><span class="kw">auto</span> not_fn<span class="op">(</span>F<span class="op">&amp;&amp;</span> f<span class="op">)</span> <span class="op">{</span></span>
<span id="cb64-3"><a href="#cb64-3"></a>    <span class="cf">return</span> <span class="op">[</span>f<span class="op">=</span>forward<span class="op">&lt;</span>F<span class="op">&gt;(</span>f<span class="op">)](</span><span class="kw">this</span> <span class="kw">auto</span><span class="op">&amp;&amp;</span> self, <span class="kw">auto</span><span class="op">&amp;&amp;..</span> args<span class="op">)</span></span>
<span id="cb64-4"><a href="#cb64-4"></a>        BOOST_HOF_RETURNS<span class="op">(</span></span>
<span id="cb64-5"><a href="#cb64-5"></a>            <span class="op">!</span>invoke<span class="op">(</span></span>
<span id="cb64-6"><a href="#cb64-6"></a>                forward_like<span class="op">&lt;</span><span class="kw">decltype</span><span class="op">(</span>self<span class="op">)&gt;(</span>f<span class="op">)</span>,</span>
<span id="cb64-7"><a href="#cb64-7"></a>                forward<span class="op">&lt;</span><span class="kw">decltype</span><span class="op">(</span>args<span class="op">)&gt;(</span>args<span class="op">)...))</span></span>
<span id="cb64-8"><a href="#cb64-8"></a>        ;</span>
<span id="cb64-9"><a href="#cb64-9"></a><span class="op">}</span></span></code></pre></div>
<h1 data-number="6" style="border-bottom:1px solid #cccccc" id="faq"><span class="header-section-number">6</span> Frequently Asked Questions<a href="#faq" class="self-link"></a></h1>
<h2 data-number="6.1" id="faq-rec-lambda-impl"><span class="header-section-number">6.1</span> On the implementability of recursive lambdas<a href="#faq-rec-lambda-impl" class="self-link"></a></h2>
<p>In San Diego, 2018, there was a question of whether recursive lambdas are implementable. They are, details follow.</p>
<p>The specific issue is the way lambdas are parsed. When parsing a <em>non-generic</em> lambda function body with a default capture, the type of <code class="sourceCode cpp">this_lambda</code> would not be dependent, because the body is <em>not a template</em>. This leads to <code class="sourceCode cpp"><span class="kw">sizeof</span><span class="op">(</span>this_lambda<span class="op">)</span></code> not being dependent either, and must therefore have an answer - and yet, it cannot, as the lambda capture is not complete, and therefore, the type of <code class="sourceCode cpp">this_lambda</code> is not complete.</p>
<p>This is a huge issue for any proposal of recursive lambdas that includes non-generic lambdas.</p>
<p>Notice, however, that the syntax this paper proposes is the following:</p>
<div class="sourceCode" id="cb65"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb65-1"><a href="#cb65-1"></a><span class="kw">auto</span> fib <span class="op">=</span> <span class="op">[](</span><span class="kw">this</span> <span class="kw">auto</span><span class="op">&amp;&amp;</span> self, <span class="dt">int</span> n<span class="op">)</span> <span class="op">{</span></span>
<span id="cb65-2"><a href="#cb65-2"></a>  <span class="cf">if</span> <span class="op">(</span>n <span class="op">&lt;</span> <span class="dv">2</span><span class="op">)</span> <span class="cf">return</span> n;</span>
<span id="cb65-3"><a href="#cb65-3"></a>  <span class="cf">return</span> self<span class="op">(</span>n<span class="op">-</span><span class="dv">1</span><span class="op">)</span> <span class="op">+</span> self<span class="op">(</span>n<span class="op">-</span><span class="dv">2</span><span class="op">)</span>;</span>
<span id="cb65-4"><a href="#cb65-4"></a><span class="op">}</span></span></code></pre></div>
<p>There is, quite obviously, no way to spell a non-generic lambda, because the lambda type is unutterable. <code class="sourceCode cpp">self</code>’s type is always dependent.</p>
<p>This makes expressions depending on <code class="sourceCode cpp">self</code> to be parsed using the regular rules of the language. Expressions involving <code class="sourceCode cpp">self</code> become dependent, and the existing language rules apply, which means both nothing new to implement, and nothing new to teach.</p>
<p>This proposal is therefore implementable, unlike any other we’ve seen to date. We would really like to thank Daveed Vandevoorde for thinking through this one with us in Aspen 2019.</p>
<h2 data-number="6.2" id="faq-demand"><span class="header-section-number">6.2</span> Would library implementers use this<a href="#faq-demand" class="self-link"></a></h2>
<p>In Kona, EWGI asked us to see whether library implementors would use this. The answer seems to be a resounding yes.</p>
<p>We have heard from Casey Carter and Jonathan Wakely that they are interested in this feature. Also, on the ewg/lewg mailing lists, this paper comes up as a solution to a surprising number of questions, and gets referenced in many papers-in-flight. A sampling of papers:</p>
<ul>
<li><span class="citation" data-cites="P0798R3">[<a href="#ref-P0798R3" role="doc-biblioref">P0798R3</a>]</span></li>
<li><span class="citation" data-cites="P1221R1">[<a href="#ref-P1221R1" role="doc-biblioref">P1221R1</a>]</span></li>
</ul>
<p>In Herb Sutter’s “Name 5 most important papers for C++”, 10 out of 289 respondents chose it. Given that the cutoff was 5, and that modules, throwing values, contracts, reflection, coroutines, linear algebra, and pattern matching were all in that list, I find the result a strong indication that it is wanted.</p>
<p>We can also report that Gašper is dearly missing this feature in <a href="https://github.com/atomgalaxy/libciabatta">libciabatta</a>, a mixin support library, as well as his regular work writing libraries.</p>
<p>On the question of whether this would get used in the standard library interfaces, the answer was “not without the ability to constrain the deduced type”, which is a feature C++ needs even without this paper, and is an orthogonal feature. The same authors were generally very enthusiastic about using this feature in their implementations.</p>
<h2 data-number="6.3" id="faq-function-ptr-type"><span class="header-section-number">6.3</span> Function Pointer Types<a href="#faq-function-ptr-type" class="self-link"></a></h2>
<p>A valid question to ask is what should be the type of this-annotated functions that have a member function equivalent? There are only two options, each with a trade-off. Please assume the existence of these three functions:</p>
<div class="sourceCode" id="cb66"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb66-1"><a href="#cb66-1"></a><span class="kw">struct</span> Y <span class="op">{</span></span>
<span id="cb66-2"><a href="#cb66-2"></a>    <span class="dt">int</span> f<span class="op">(</span><span class="dt">int</span>, <span class="dt">int</span><span class="op">)</span> <span class="kw">const</span><span class="op">&amp;</span>;         <span class="co">// exists</span></span>
<span id="cb66-3"><a href="#cb66-3"></a>    <span class="dt">int</span> g<span class="op">(</span><span class="kw">this</span> Y <span class="kw">const</span><span class="op">&amp;</span>, <span class="dt">int</span>, <span class="dt">int</span><span class="op">)</span>; <span class="co">// this paper</span></span>
<span id="cb66-4"><a href="#cb66-4"></a>    <span class="dt">int</span> h<span class="op">(</span><span class="kw">this</span> Y, <span class="dt">int</span>, <span class="dt">int</span><span class="op">)</span>;        <span class="co">// this paper, by value</span></span>
<span id="cb66-5"><a href="#cb66-5"></a><span class="op">}</span>;</span></code></pre></div>
<p><code class="sourceCode cpp">g</code> has a current equivalent (<code class="sourceCode cpp">f</code>), while <code class="sourceCode cpp">h</code> does not. <code class="sourceCode cpp"><span class="op">&amp;</span>Y<span class="op">::</span>h</code>’s type <em>must</em> be a regular function pointer.</p>
<p>If we allow <code class="sourceCode cpp">g</code>’s type to be a pointer-to-member-function, we get non-uniformity between the types of <code class="sourceCode cpp">h</code> and <code class="sourceCode cpp">g</code>. We also get implementation issues because the types a template can result in are non-uniform (is this a template for a member function or a free function? Surprise, it’s both!).</p>
<p>We also get forward compatibility with any concievable proposal for extension methods - those will <em>also</em> have to be free functions by necessity, for roughly the same reasons.</p>
<p>The paper originally proposed it the other way, but this was changed to the current wording through EWG input in Cologne, 2018.</p>
<h2 data-number="6.4" id="faq-computed-deduction"><span class="header-section-number">6.4</span> Deducing to Base-Class Pointer<a href="#faq-computed-deduction" class="self-link"></a></h2>
<p>One of the pitfalls of having a deduced object parameter is when the intent is solely to deduce the <em>cv</em>-qualifiers and value category of the object parameter, but a derived type is deduced as well — any access through an object that might have a derived type could inadvertently refer to a shadowed member in the derived class. While this is desirable and very powerful in the case of mixins, it is not always desirable in other situations. Superfluous template instantiations are also unwelcome side effects.</p>
<p>One family of possible solutions could be summarized as <strong>make it easy to get the base class pointer</strong>. However, all of these solutions still require extra instantiations. For <code class="sourceCode cpp">optional<span class="op">::</span>value<span class="op">()</span></code>, we really only want four instantiations: <code class="sourceCode cpp"><span class="op">&amp;</span></code>, <code class="sourceCode cpp"><span class="kw">const</span><span class="op">&amp;</span></code>, <code class="sourceCode cpp"><span class="op">&amp;&amp;</span></code>, and <code class="sourceCode cpp"><span class="kw">const</span><span class="op">&amp;&amp;</span></code>. If something inherits from <code class="sourceCode cpp">optional</code>, we don’t want additional instantiations of those functions for the derived types, which won’t do anything new, anyway. This is code bloat.</p>
<p><em>This is already a problem for free-function templates</em>: The authors have heard many a complaint about it from library vendors, even before this paper was introduced, as it is desirable to only deduce the ref-qualifier in many contexts. Therefore, it might make sense to tackle this issue in a more general way. A complementary feature could be proposed to constrain <em>type deduction</em>.</p>
<p>The authors strongly believe this feature is orthogonal. However, hoping that mentioning that solutions are in the pipeline helps gain consensus for this paper, we mention one solution here. The proposal is in early stages, and is not in the pre-belfast mailing. It will be present in the post-belfast mailing: <a href="https://atomgalaxy.github.io/isocpp-1107/D1107.html">computed deduction</a></p>
<h2 data-number="6.5" id="was-this-syntax-considered"><span class="header-section-number">6.5</span> Was this syntax considered?<a href="#was-this-syntax-considered" class="self-link"></a></h2>
<p>In the course of working on this paper, many different syntaxes were considered for how to properly express this idea. Those various options have been culled from previous revisions of the paper, but we should have always kept them in for posterity. So we’re adding them in here.</p>
<p><span class="citation" data-cites="P0847R0">[<a href="#ref-P0847R0" role="doc-biblioref">P0847R0</a>]</span> originally proposed the syntax as:</p>
<div class="sourceCode" id="cb67"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb67-1"><a href="#cb67-1"></a><span class="kw">struct</span> X <span class="op">{</span></span>
<span id="cb67-2"><a href="#cb67-2"></a>    <span class="co">// an explicit object parameter named self</span></span>
<span id="cb67-3"><a href="#cb67-3"></a>    <span class="dt">void</span> f<span class="op">(</span>X<span class="op">&amp;</span> <span class="kw">this</span> self<span class="op">)</span>;</span>
<span id="cb67-4"><a href="#cb67-4"></a>    </span>
<span id="cb67-5"><a href="#cb67-5"></a>    <span class="co">// an unnamed, deduced explicit object parameter</span></span>
<span id="cb67-6"><a href="#cb67-6"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> Self<span class="op">&gt;</span></span>
<span id="cb67-7"><a href="#cb67-7"></a>    <span class="dt">void</span> g<span class="op">(</span>Self<span class="op">&amp;&amp;</span> <span class="kw">this</span><span class="op">)</span>;</span>
<span id="cb67-8"><a href="#cb67-8"></a><span class="op">}</span>;</span></code></pre></div>
<p><span class="citation" data-cites="P0847R1">[<a href="#ref-P0847R1" role="doc-biblioref">P0847R1</a>]</span> considered four potential syntaxes. We’ll present them here again with a trivial example that simply returns a member variable, without any deduction.</p>
<ol type="1">
<li>An explicit <code class="sourceCode cpp"><span class="kw">this</span></code>-annotated parameter. We took the R0 syntax and reordered it so that <code class="sourceCode cpp"><span class="kw">this</span></code> precedes the parameter declaration rather than being in the middle of it.</li>
<li>An explicit parameter <em>named</em> <code class="sourceCode cpp"><span class="kw">this</span></code>. That is, the first parameter <em>must</em> be named <code class="sourceCode cpp"><span class="kw">this</span></code>, which would then become an object rather than a pointer.</li>
<li>Having a trailing type (rather than just cv- and ref-qualifiers) with an identifier</li>
<li>Having a trailing type (as above) just without an identifier.</li>
</ol>
<p>Putting them all in a single example:</p>
<div class="sourceCode" id="cb68"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb68-1"><a href="#cb68-1"></a><span class="kw">struct</span> A <span class="op">{</span></span>
<span id="cb68-2"><a href="#cb68-2"></a>    <span class="co">// #1</span></span>
<span id="cb68-3"><a href="#cb68-3"></a>    <span class="dt">int</span> get<span class="op">(</span><span class="kw">this</span> A <span class="kw">const</span><span class="op">&amp;</span> a<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> a<span class="op">.</span>i; <span class="op">}</span></span>
<span id="cb68-4"><a href="#cb68-4"></a>    </span>
<span id="cb68-5"><a href="#cb68-5"></a>    <span class="co">// #2</span></span>
<span id="cb68-6"><a href="#cb68-6"></a>    <span class="dt">int</span> get<span class="op">(</span>A <span class="kw">const</span><span class="op">&amp;</span> <span class="kw">this</span><span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> <span class="kw">this</span><span class="op">.</span>i; <span class="op">}</span></span>
<span id="cb68-7"><a href="#cb68-7"></a>    </span>
<span id="cb68-8"><a href="#cb68-8"></a>    <span class="co">// #3</span></span>
<span id="cb68-9"><a href="#cb68-9"></a>    <span class="dt">int</span> get<span class="op">()</span> A <span class="kw">const</span><span class="op">&amp;</span> self <span class="op">{</span> <span class="cf">return</span> self<span class="op">.</span>i; <span class="op">}</span></span>
<span id="cb68-10"><a href="#cb68-10"></a>    </span>
<span id="cb68-11"><a href="#cb68-11"></a>    <span class="co">// #4</span></span>
<span id="cb68-12"><a href="#cb68-12"></a>    <span class="dt">int</span> get<span class="op">()</span> A <span class="kw">const</span><span class="op">&amp;</span> <span class="op">{</span> <span class="cf">return</span> <span class="kw">this</span><span class="op">-&gt;</span>i; <span class="op">}</span></span>
<span id="cb68-13"><a href="#cb68-13"></a>    </span>
<span id="cb68-14"><a href="#cb68-14"></a>    <span class="dt">int</span> i;</span>
<span id="cb68-15"><a href="#cb68-15"></a><span class="op">}</span>;</span></code></pre></div>
<p>We ended up settling on option <code class="sourceCode cpp"><span class="pp">#1</span></code> (as can be seen from the rest of this paper). The syntax isn’t especially adventurous and solves all the use-cases we want to solve, and compares very favorably to the rest.</p>
<p>While options <code class="sourceCode cpp"><span class="pp">#3</span></code> and <code class="sourceCode cpp"><span class="pp">#4</span></code> keep the cv- and ref-qualifiers where they are today, so in some sense they are more familiar, there were other issues with them overall that led us to where we are today. <code class="sourceCode cpp"><span class="pp">#3</span></code> has parsing issues, <code class="sourceCode cpp"><span class="pp">#4</span></code> doesn’t work for lambdas and would have to have <code class="sourceCode cpp"><span class="kw">this</span></code> be potentially dependent, neither allows by-value member functions. <code class="sourceCode cpp"><span class="pp">#2</span></code> would provide meaning to parameter names that doesn’t currently exist today, would give a very different interpretation to <code class="sourceCode cpp"><span class="kw">this</span></code> than the one we’ve always had in C++, and would have fairly poor interaction with lambdas that may need to capture <code class="sourceCode cpp"><span class="kw">this</span></code>.</p>
<h1 data-number="7" style="border-bottom:1px solid #cccccc" id="reflection"><span class="header-section-number">7</span> Reflection<a href="#reflection" class="self-link"></a></h1>
<p>One question that has come up periodically is: would we still need this language feature if we had a reflection facility that offered code injection (as described in <span class="citation" data-cites="P2237R0">[<a href="#ref-P2237R0" role="doc-biblioref">P2237R0</a>]</span>)? We can answer this question by going through the use-cases we’ve presented in this paper and try to figure out how well they could be resolved by a code-injection facility.</p>
<h2 data-number="7.1" id="deduplicating-code-1"><span class="header-section-number">7.1</span> Deduplicating Code<a href="#deduplicating-code-1" class="self-link"></a></h2>
<p>Of the five use-cases, this one is the most up in the air. This one seems unlikely to be well-handled by code injection, but it really depends on the kinds of facilities injection will end up allowing. Let’s consider the simplest possible case:</p>
<div class="sourceCode" id="cb69"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb69-1"><a href="#cb69-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="cb69-2"><a href="#cb69-2"></a><span class="kw">struct</span> not_very_optional <span class="op">{</span></span>
<span id="cb69-3"><a href="#cb69-3"></a>    T value;</span>
<span id="cb69-4"><a href="#cb69-4"></a></span>
<span id="cb69-5"><a href="#cb69-5"></a>    <span class="kw">auto</span> get<span class="op">()</span> <span class="op">&amp;</span> <span class="op">-&gt;</span> T<span class="op">&amp;</span> <span class="op">{</span> <span class="cf">return</span> value; <span class="op">}</span></span>
<span id="cb69-6"><a href="#cb69-6"></a>    <span class="kw">auto</span> get<span class="op">()</span> <span class="kw">const</span><span class="op">&amp;</span> <span class="op">-&gt;</span> T <span class="kw">const</span><span class="op">&amp;</span> <span class="op">{</span> <span class="cf">return</span> value; <span class="op">}</span></span>
<span id="cb69-7"><a href="#cb69-7"></a>    <span class="kw">auto</span> get<span class="op">()</span> <span class="op">&amp;&amp;</span> <span class="op">-&gt;</span> T <span class="kw">const</span><span class="op">&amp;</span> <span class="op">{</span> <span class="cf">return</span> std<span class="op">::</span>move<span class="op">(</span>value<span class="op">)</span>; <span class="op">}</span></span>
<span id="cb69-8"><a href="#cb69-8"></a>    <span class="kw">auto</span> get<span class="op">()</span> <span class="kw">const</span><span class="op">&amp;&amp;</span> <span class="op">-&gt;</span> T <span class="kw">const</span><span class="op">&amp;&amp;</span> <span class="op">{</span> <span class="cf">return</span> std<span class="op">::</span>move<span class="op">(</span>value<span class="op">)</span>; <span class="op">}</span></span>
<span id="cb69-9"><a href="#cb69-9"></a><span class="op">}</span>;</span></code></pre></div>
<p>As presented earlier, one way to do this is to implement three of these in terms of the fourth. For this case, this is something that potentially could be handled through injection, as in this way demonstrated on the reflectors by Ville Voutilainen:</p>
<div class="sourceCode" id="cb70"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb70-1"><a href="#cb70-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="cb70-2"><a href="#cb70-2"></a><span class="kw">struct</span> not_very_optional <span class="op">{</span></span>
<span id="cb70-3"><a href="#cb70-3"></a>    T value;</span>
<span id="cb70-4"><a href="#cb70-4"></a></span>
<span id="cb70-5"><a href="#cb70-5"></a>    <span class="kw">auto</span> get<span class="op">()</span> <span class="op">&amp;</span> <span class="op">-&gt;</span> T<span class="op">&amp;</span> <span class="op">{</span> <span class="cf">return</span> value; <span class="op">}</span></span>
<span id="cb70-6"><a href="#cb70-6"></a>    </span>
<span id="cb70-7"><a href="#cb70-7"></a>    <span class="kw">consteval</span> <span class="op">{</span></span>
<span id="cb70-8"><a href="#cb70-8"></a>        std<span class="op">::</span>meta<span class="op">::</span>gen_crval_overloads<span class="op">(</span>reflexpr<span class="op">(</span>not_very_optional<span class="op">::</span>get<span class="op">))</span>;</span>
<span id="cb70-9"><a href="#cb70-9"></a>    <span class="op">}</span>    </span>
<span id="cb70-10"><a href="#cb70-10"></a><span class="op">}</span>;</span></code></pre></div>
<p>Although it’s not clear if this pattern would work for more complex overload sets. As in, if the different overloads needed different constraints or had different <code class="sourceCode cpp"><span class="kw">noexcept</span></code> specifications:</p>
<div class="sourceCode" id="cb71"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb71-1"><a href="#cb71-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="cb71-2"><a href="#cb71-2"></a><span class="kw">struct</span> still_not_very_optional <span class="op">{</span></span>
<span id="cb71-3"><a href="#cb71-3"></a>    <span class="kw">auto</span> map<span class="op">(</span>invocable<span class="op">&lt;</span>T<span class="op">&amp;&gt;</span> <span class="kw">auto</span><span class="op">&amp;&amp;)</span> <span class="op">&amp;</span>;</span>
<span id="cb71-4"><a href="#cb71-4"></a>    <span class="kw">auto</span> map<span class="op">(</span>invocable<span class="op">&lt;</span>T <span class="kw">const</span><span class="op">&amp;&gt;</span> <span class="kw">auto</span><span class="op">&amp;&amp;)</span> <span class="kw">const</span><span class="op">&amp;</span>;</span>
<span id="cb71-5"><a href="#cb71-5"></a>    <span class="kw">auto</span> map<span class="op">(</span>invocable<span class="op">&lt;</span>T<span class="op">&amp;&amp;&gt;</span> <span class="kw">auto</span><span class="op">&amp;&amp;)</span> <span class="op">&amp;&amp;</span>;</span>
<span id="cb71-6"><a href="#cb71-6"></a>    <span class="kw">auto</span> map<span class="op">(</span>invocable<span class="op">&lt;</span>T <span class="kw">const</span><span class="op">&amp;&amp;&gt;</span> <span class="kw">auto</span><span class="op">&amp;&amp;)</span> <span class="kw">const</span><span class="op">&amp;&amp;</span>;</span>
<span id="cb71-7"><a href="#cb71-7"></a><span class="op">}</span>;</span></code></pre></div>
<p>This doesn’t really translate in the <code class="sourceCode cpp">gen_crval_overloads</code> model. You could do this sort of thing with macros:</p>
<div class="sourceCode" id="cb72"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb72-1"><a href="#cb72-1"></a><span class="pp">#define INJECT_QUALS</span><span class="op">(</span>X<span class="op">)</span><span class="pp"> </span>X<span class="op">(&amp;)</span><span class="pp"> </span>X<span class="op">(</span><span class="kw">const</span><span class="op">&amp;)</span><span class="pp"> </span>X<span class="op">(&amp;&amp;)</span><span class="pp"> </span>X<span class="op">(</span><span class="kw">const</span><span class="op">&amp;&amp;)</span></span>
<span id="cb72-2"><a href="#cb72-2"></a></span>
<span id="cb72-3"><a href="#cb72-3"></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="cb72-4"><a href="#cb72-4"></a><span class="kw">struct</span> still_not_very_optional <span class="op">{</span></span>
<span id="cb72-5"><a href="#cb72-5"></a>    <span class="pp">#define MAP_QUALS</span><span class="op">(</span>q<span class="op">)</span><span class="pp"> </span><span class="kw">auto</span><span class="pp"> </span>map<span class="op">(</span>invocable<span class="op">&lt;</span>T<span class="pp"> </span>q<span class="op">&gt;</span><span class="pp"> </span><span class="kw">auto</span><span class="op">&amp;&amp;)</span><span class="pp"> </span>q;</span>
<span id="cb72-6"><a href="#cb72-6"></a>    INJECT_QUALS<span class="op">(</span>MAP_QUALS<span class="op">)</span></span>
<span id="cb72-7"><a href="#cb72-7"></a><span class="op">}</span>;</span></code></pre></div>
<p>Which suggests a potential code injection direction if we could inject qualifiers somehow, which is a feature that the Metaprogramming paper does not mention, and it is unclear if that is a direction that will be pursued.</p>
<p>As a result, we have to state that reflection as proposed thus far would not really address this use-case.</p>
<h2 data-number="7.2" id="better-mixin-support"><span class="header-section-number">7.2</span> Better mixin support<a href="#better-mixin-support" class="self-link"></a></h2>
<p>Deducing this provides us a better way to write mixins. But mixins are an especially clear use-case for code injection, and one that code injection could easily provide a superior alternative.</p>
<p>We presented an example with postfix increment earlier in the paper, here is how that example could look with code injection:</p>
<table style="width:100%">
<tr>
<th style="width:50%">
Proposed in this paper
</th>
<th style="width:50%">
With reflection
</th>
</tr>
<tr>
<td>
<div class="sourceCode" id="cb73"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb73-1"><a href="#cb73-1"></a><span class="kw">struct</span> add_postfix_increment <span class="op">{</span></span>
<span id="cb73-2"><a href="#cb73-2"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> Self<span class="op">&gt;</span></span>
<span id="cb73-3"><a href="#cb73-3"></a>    <span class="kw">auto</span> <span class="kw">operator</span><span class="op">++(</span><span class="kw">this</span> Self<span class="op">&amp;&amp;</span> self, <span class="dt">int</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb73-4"><a href="#cb73-4"></a>        <span class="kw">auto</span> tmp <span class="op">=</span> self;</span>
<span id="cb73-5"><a href="#cb73-5"></a>        <span class="op">++</span>self;</span>
<span id="cb73-6"><a href="#cb73-6"></a>        <span class="cf">return</span> tmp;</span>
<span id="cb73-7"><a href="#cb73-7"></a>    <span class="op">}</span></span>
<span id="cb73-8"><a href="#cb73-8"></a><span class="op">}</span>;</span>
<span id="cb73-9"><a href="#cb73-9"></a></span>
<span id="cb73-10"><a href="#cb73-10"></a><span class="kw">struct</span> some_type <span class="op">:</span> add_postfix_increment <span class="op">{</span></span>
<span id="cb73-11"><a href="#cb73-11"></a>    some_type<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">++()</span> <span class="op">{</span> <span class="op">...</span> <span class="op">}</span></span>
<span id="cb73-12"><a href="#cb73-12"></a><span class="op">}</span>;</span></code></pre></div>
</td>
<td>
<div class="sourceCode" id="cb74"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb74-1"><a href="#cb74-1"></a><span class="kw">constexpr</span> <span class="kw">auto</span> add_postfix_increment <span class="op">=</span></span>
<span id="cb74-2"><a href="#cb74-2"></a>    <span class="op">&lt;</span><span class="kw">struct</span> T<span class="op">{</span></span>
<span id="cb74-3"><a href="#cb74-3"></a>        T <span class="kw">operator</span><span class="op">++(</span><span class="dt">int</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb74-4"><a href="#cb74-4"></a>            T tmp <span class="op">=</span> <span class="op">*</span><span class="kw">this</span>;</span>
<span id="cb74-5"><a href="#cb74-5"></a>            <span class="op">++*</span><span class="kw">this</span>;</span>
<span id="cb74-6"><a href="#cb74-6"></a>            <span class="cf">return</span> tmp;</span>
<span id="cb74-7"><a href="#cb74-7"></a>        <span class="op">}</span></span>
<span id="cb74-8"><a href="#cb74-8"></a>    <span class="op">}&gt;</span>;</span>
<span id="cb74-9"><a href="#cb74-9"></a></span>
<span id="cb74-10"><a href="#cb74-10"></a><span class="kw">struct</span> some_type <span class="op">{</span></span>
<span id="cb74-11"><a href="#cb74-11"></a>    some_type<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">++()</span> <span class="op">{</span> <span class="op">...</span> <span class="op">}</span></span>
<span id="cb74-12"><a href="#cb74-12"></a>    <span class="op">&lt;&lt;</span> add_postfix_increment;</span>
<span id="cb74-13"><a href="#cb74-13"></a><span class="op">}</span>;</span></code></pre></div>
</td>
</tr>
</table>
<p>Assuming this is roughly how the code injection facility will look, we expect the code on the right to be preferred in many use-cases. While obviously novel for C++, it’s also simpler (there are no templates) and it is a more direct and less intrusive way to add functionality to a class (<code class="sourceCode cpp">some_type</code> no longer needs to have a base class, which is a meaningful benefit).</p>
<h2 data-number="7.3" id="the-other-three"><span class="header-section-number">7.3</span> The other three<a href="#the-other-three" class="self-link"></a></h2>
<p>The other three use-cases presented in this paper are recursive lambdas, by-value member functions, and the ability to properly create SFINAE-friendly call wrappers. What all of these use-cases have in common is that they are all cases you cannot write today. You cannot write a recursive lambda because you have no way of naming the lambda itself from its body, you cannot write a by-value member function since the object parameter of non-static member functions is always a reference, and you cannot create SFINAE-friendly call wrappers since you cannot write the wrapper as a single function template.</p>
<p>The ability to deduce this — to treat the object parameter as a first-class function parameter — is a new language feature that allows us to do all of these things. It gives us the ability to name the lambda, to take the object parameter by value, and to write a single function template for call wrappers rather than writing four different call operators.</p>
<p>Code injection facilities can only inject code that you could already write yourself by hand. As such, no matter where reflection takes us, it could not provide solutions for these problems since they fundamentally require new language support.</p>
<p>Potentially, reflection could provide some magic <code class="sourceCode cpp">std<span class="op">::</span>meta<span class="op">::</span>get_current_lambda<span class="op">()</span></code> function that when invoked from within a lambda body could give you access to the lambda itself. But this would have to be a facility provided by a compiler intrinsic and seems like an especially unsatisfying solution as compared to the one presented in this paper.</p>
<h2 data-number="7.4" id="reflection-vs-deducing-this"><span class="header-section-number">7.4</span> Reflection vs deducing this<a href="#reflection-vs-deducing-this" class="self-link"></a></h2>
<p>Of the five use-cases presented in this paper, we expect Reflection to provide a superior solution to one of them. But it basically cannot solve three of them, and it is unclear to what extent it would be able to provide a satisfactory solution to the fifth. As a result, Reflection can’t really be a substitute for this proposal on the whole, even if we could get the facilities described in the Metaprogramming paper right away.</p>
<h1 data-number="8" style="border-bottom:1px solid #cccccc" id="implementation"><span class="header-section-number">8</span> Implementation<a href="#implementation" class="self-link"></a></h1>
<p>This has been implemented in the EDG front end, with gracious help and encouragement from Daveed Vandevoorde. Implementation didn’t turn up any notable issues.</p>
<h1 data-number="9" style="border-bottom:1px solid #cccccc" id="wording"><span class="header-section-number">9</span> Proposed Wording<a href="#wording" class="self-link"></a></h1>
<h2 data-number="9.1" id="overview"><span class="header-section-number">9.1</span> Overview<a href="#overview" class="self-link"></a></h2>
<p>The status quo here is that a member function has an <em>implicit object parameter</em>, always of reference type, which the <em>implied object argument</em> is bound to. The obvious name for what this paper is proposing is, then, the <em>explicit object parameter</em>. The problem with these names is: well, what is an object parameter? A parameter that takes an object? Isn’t that most parameters?</p>
<p>However, calling it a <em>this parameter</em> is confusing in a different way: <code class="sourceCode cpp"><span class="kw">this</span></code> is a pointer, and the parameter in question would always be either a reference type (as is always the case today) or a value (as is possible with this feature), never a pointer.</p>
<p>We considered a lot of other terms - self parameter, selector parameter, instance parameter, subject parameter, target parameter. But we kind of feel like maybe “object parameter” is actually fine? In classical OO, perhaps “subject” might be better than “object”, but maybe object is good enough.</p>
<h2 data-number="9.2" id="wording-1"><span class="header-section-number">9.2</span> Wording<a href="#wording-1" class="self-link"></a></h2>
<div class="ednote" style="color: #0000ff">
<p>[ Editor&#39;s note: This paper introduces many new terms that are defined in [dcl.dcl] - so even though the wording here is presented in standard layout order (we obviously want to ensure that <code class="sourceCode default">is_standard_layout&lt;P0847&gt;</code> is <code class="sourceCode default">true</code>), it may be helpful to refer to <a href="#dcl.dcl">those definitions</a> when reviewing the wording.</p>
<p>One decision was to introduce the term <em>object parameter</em> as the union of explicit object parameter (new in this paper) and implicit object parameter (preexisting). This is the difference between making changes like “implicit <span class="addu">or explicit</span> object parameter” in a bunch of places vs “<span class="rm" style="color: #bf0303"><del>implicit</del></span> object parameter” in a bunch of places. ]</p>
</div>
<h3 data-number="9.2.1" id="wording-in-basic"><span class="header-section-number">9.2.1</span> Wording in <span>6
 <a href="https://wg21.link/basic">[basic]</a></span><a href="#wording-in-basic" class="self-link"></a></h3>
<p>Extend the definition of correspond<a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a> in <span>6.4.1
 <a href="https://wg21.link/basic.scope.scope">[basic.scope.scope]</a></span>/3 to check the implicit/explicit object parameter types:</p>
<blockquote>
<div class="addu">
<p><span class="marginalizedparent"><a class="marginalized">a</a></span> Two non-static member functions have <em>corresponding object parameters</em> if:</p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">(a.1)</a></span> exactly one is an implicit object member function with no <em>ref-qualifier</em> and the types of their object parameters ([dcl.fct]), after removing top-level references, are the same, or</li>
<li><span class="marginalizedparent"><a class="marginalized">(a.2)</a></span> their object parameters have the same type.</li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">b</a></span> Two non-static member function templates have <em>corresponding object parameters</em> if:</p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">(b.1)</a></span> exactly one is an implicit object member function with no <em>ref-qualifier</em> and the types of their object parameters, after removing any references, are equivalent, or</li>
<li><span class="marginalizedparent"><a class="marginalized">(b.2)</a></span> the types of their object parameters are equivalent.</li>
</ul>
</div>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span> Two declarations <em>correspond</em> if they (re)introduce the same name, both declare constructors, or both declare destructors, unless</p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(3.1)</a></span> either is a <em>using-declarator</em>, or</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(3.2)</a></span> one declares a type (not a <em>typedef-name</em>) and the other declares a variable, non-static data member other than of an anonymous union ([class.union.anon]), enumerator, function, or function template, or</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(3.3)</a></span> each declares a function or function template, except when</p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">(3.3.1)</a></span> both declare functions with the same <span class="addu">non-object-</span>parameter-type-list<sup>21</sup>, equivalent ([temp.over.link]) trailing <em>requires-clause</em>s (if any, except as specified in [temp.friend]), and, if both are non-static members, <span class="rm" style="color: #bf0303"><del>the same <em>cv-qualifier</em>s (if any) and <em>ref-qualifier</em> (if both have one)</del></span> <span class="addu">they have corresponding object parameters</span>, or</li>
<li><span class="marginalizedparent"><a class="marginalized">(3.3.2)</a></span> both declare function templates with equivalent <span class="addu">non-object-</span>parameter-type-lists, return types (if any), <em>template-head</em>s, and trailing <em>requires-clause</em>s (if any), and, if both are non-static members, <span class="rm" style="color: #bf0303"><del>the same <em>cv-qualifier</em>s (if any) and <em>ref-qualifier</em> (if both have one)</del></span> <span class="addu">they have corresponding object parameters</span>.</li>
</ul></li>
</ul>
</blockquote>
<p>and extend the example:</p>
<blockquote>
<div>
<div class="sourceCode" id="cb79"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb79-1"><a href="#cb79-1"></a>  typedef int Int;</span>
<span id="cb79-2"><a href="#cb79-2"></a>  enum E : int { a };</span>
<span id="cb79-3"><a href="#cb79-3"></a>  void f(int);            // #1</span>
<span id="cb79-4"><a href="#cb79-4"></a>  void f(Int) {}          // defines #1</span>
<span id="cb79-5"><a href="#cb79-5"></a>  void f(E) {}            // OK: another overload</span>
<span id="cb79-6"><a href="#cb79-6"></a>  </span>
<span id="cb79-7"><a href="#cb79-7"></a>  struct X {</span>
<span id="cb79-8"><a href="#cb79-8"></a>    static void f();</span>
<span id="cb79-9"><a href="#cb79-9"></a>    void f() const;       // error: redeclaration</span>
<span id="cb79-10"><a href="#cb79-10"></a>    void g();</span>
<span id="cb79-11"><a href="#cb79-11"></a>    void g() const;       // OK</span>
<span id="cb79-12"><a href="#cb79-12"></a>    void g() &amp;;           // error: redeclaration</span>
<span id="cb79-13"><a href="#cb79-13"></a>    </span>
<span id="cb79-14"><a href="#cb79-14"></a><span class="va">+   void h(this X&amp;, int);</span></span>
<span id="cb79-15"><a href="#cb79-15"></a><span class="va">+   void h(int) &amp;&amp;;               // OK: another overload</span></span>
<span id="cb79-16"><a href="#cb79-16"></a><span class="va">+   void j(this const X&amp;);</span></span>
<span id="cb79-17"><a href="#cb79-17"></a><span class="va">+   void j() const&amp;;              // error: redeclaration</span></span>
<span id="cb79-18"><a href="#cb79-18"></a><span class="va">+   void k();</span></span>
<span id="cb79-19"><a href="#cb79-19"></a><span class="va">+   void k(this X&amp;);              // error: redeclaration</span></span>
<span id="cb79-20"><a href="#cb79-20"></a>  };</span></code></pre></div>
</div>
</blockquote>
<h3 data-number="9.2.2" id="wording-in-expr"><span class="header-section-number">9.2.2</span> Wording in <span>7
 <a href="https://wg21.link/expr">[expr]</a></span><a href="#wording-in-expr" class="self-link"></a></h3>
<p>Change <span>7.5.2
 <a href="https://wg21.link/expr.prim.this">[expr.prim.this]</a></span>/1 and /3:</p>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span> The keyword <code class="sourceCode cpp"><span class="kw">this</span></code> names a pointer to the object for which <span class="rm" style="color: #bf0303"><del>a non-static</del></span> <span class="addu">an implicit object</span> member function ([class.mfct.non-static]) is invoked or a non-static data member’s initializer ([class.mem]) is evaluated.</p>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span> It shall not appear within the declaration of <span class="addu">either</span> a static member function <span class="addu">or an explicit object member function</span> of the current class (although its type and value category are defined within <span class="rm" style="color: #bf0303"><del>a static</del></span> <span class="addu">such</span> member function<span class="addu">s</span> as they are within <span class="rm" style="color: #bf0303"><del>a non-static</del></span> <span class="addu">an implicit object</span> member function).</p>
</blockquote>
<p>Change <span>7.5.4
 <a href="https://wg21.link/expr.prim.id">[expr.prim.id]</a></span>/2 to properly account for lambdas with an explicit object parameter:</p>
<blockquote>
<p>The result is the entity denoted by the identifier. If the entity is a local entity and naming it from outside of an unevaluated operand within the declarative region where the <em>unqualified-id</em> appears would result in some intervening <em>lambda-expression</em> capturing it by copy ([expr.prim.lambda.capture]), the type of the expression is the type of a class member access expression ([expr.ref]) naming the non-static data member that would be declared for such a capture in the <span class="rm" style="color: #bf0303"><del>closure object</del></span> <span class="addu">object parameter ([dcl.fct]) of the function call operator of the</span> innermost such intervening <em>lambda-expression</em>.</p>
</blockquote>
<p>Change <span>7.5.5
 <a href="https://wg21.link/expr.prim.lambda">[expr.prim.lambda]</a></span>/3:</p>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span> In the <em>decl-specifier-seq</em> of the <em>lambda-declarator</em>, each <em>decl-specifier</em> shall be one of <code class="sourceCode cpp"><span class="kw">mutable</span></code>, <code class="sourceCode cpp"><span class="kw">constexpr</span></code>, or <code class="sourceCode cpp"><span class="kw">consteval</span></code>. <span class="addu">If the <em>lambda-declarator</em> contains an explicit object parameter ([dcl.fct]), then no <em>decl-specifier</em> in the <em>decl-specifier-seq</em> shall be <code class="sourceCode cpp"><span class="kw">mutable</span></code>.</span> [ Note: The trailing requires-clause is described in [dcl.decl]. — end note ]</p>
</blockquote>
<p>Extend the example in <span>7.5.5.2
 <a href="https://wg21.link/expr.prim.lambda.closure">[expr.prim.lambda.closure]</a></span>/3:</p>
<blockquote>
<div>
<div class="sourceCode" id="cb80"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb80-1"><a href="#cb80-1"></a>  auto glambda = [](auto a, auto&amp;&amp; b) { return a &lt; b; };</span>
<span id="cb80-2"><a href="#cb80-2"></a>  bool b = glambda(3, 3.14);                                      // OK</span>
<span id="cb80-3"><a href="#cb80-3"></a>  </span>
<span id="cb80-4"><a href="#cb80-4"></a>  auto vglambda = [](auto printer) {</span>
<span id="cb80-5"><a href="#cb80-5"></a>    return [=](auto&amp;&amp; ... ts) {                                   // OK: ts is a function parameter pack</span>
<span id="cb80-6"><a href="#cb80-6"></a>      printer(std::forward&lt;decltype(ts)&gt;(ts)...);</span>
<span id="cb80-7"><a href="#cb80-7"></a>  </span>
<span id="cb80-8"><a href="#cb80-8"></a>      return [=]() {</span>
<span id="cb80-9"><a href="#cb80-9"></a>        printer(ts ...);</span>
<span id="cb80-10"><a href="#cb80-10"></a>      };</span>
<span id="cb80-11"><a href="#cb80-11"></a>    };</span>
<span id="cb80-12"><a href="#cb80-12"></a>  };</span>
<span id="cb80-13"><a href="#cb80-13"></a>  auto p = vglambda( [](auto v1, auto v2, auto v3)</span>
<span id="cb80-14"><a href="#cb80-14"></a>                     { std::cout &lt;&lt; v1 &lt;&lt; v2 &lt;&lt; v3; } );</span>
<span id="cb80-15"><a href="#cb80-15"></a>  auto q = p(1, &#39;a&#39;, 3.14);                                       // OK: outputs 1a3.14</span>
<span id="cb80-16"><a href="#cb80-16"></a>  q();                                                            // OK: outputs 1a3.14</span>
<span id="cb80-17"><a href="#cb80-17"></a><span class="va">+ </span></span>
<span id="cb80-18"><a href="#cb80-18"></a><span class="va">+ auto fact = [](this auto self, int n) -&gt; int {                  // OK: explicit object parameter</span></span>
<span id="cb80-19"><a href="#cb80-19"></a><span class="va">+    return (n &lt;= 1) ? 1 : n * self(n-1);</span></span>
<span id="cb80-20"><a href="#cb80-20"></a><span class="va">+ };</span></span>
<span id="cb80-21"><a href="#cb80-21"></a><span class="va">+ std::cout &lt;&lt; fact(5);                                           // OK: outputs 120</span></span></code></pre></div>
</div>
</blockquote>
<p>Add a new paragraph after <span>7.5.5.2
 <a href="https://wg21.link/expr.prim.lambda.closure">[expr.prim.lambda.closure]</a></span>/3:</p>
<blockquote>
<div class="addu">
<p><span class="marginalizedparent"><a class="marginalized">3*</a></span> Given a lambda with a <em>lambda-capture</em>, the type of the explicit object parameter, if any, of the lambda’s function call operator (possibly instantiated from a function call operator template) shall be either:</p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">(3*.1)</a></span> the closure type,</li>
<li><span class="marginalizedparent"><a class="marginalized">(3*.2)</a></span> a class type derived from the closure type, or</li>
<li><span class="marginalizedparent"><a class="marginalized">(3*.3)</a></span> a reference to a possibly cv-qualified such type.</li>
</ul>
<p>[ <em>Example</em>:</p>
<div class="sourceCode" id="cb81"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb81-1"><a href="#cb81-1"></a>struct C {</span>
<span id="cb81-2"><a href="#cb81-2"></a>    template &lt;typename T&gt;</span>
<span id="cb81-3"><a href="#cb81-3"></a>    C(T);</span>
<span id="cb81-4"><a href="#cb81-4"></a>};</span>
<span id="cb81-5"><a href="#cb81-5"></a></span>
<span id="cb81-6"><a href="#cb81-6"></a>void func(int i) {</span>
<span id="cb81-7"><a href="#cb81-7"></a>    int x = [=](this auto&amp;&amp;) { return i; }(); // ok</span>
<span id="cb81-8"><a href="#cb81-8"></a>    int y = [=](this C) { return i; }();      // ill-formed</span>
<span id="cb81-9"><a href="#cb81-9"></a>    int z = [](this C) { return 42; }();      // ok</span>
<span id="cb81-10"><a href="#cb81-10"></a>}</span></code></pre></div>
<ul>
<li><em>end example</em> ]</li>
</ul>
</div>
</blockquote>
<p>Change <span>7.5.5.2
 <a href="https://wg21.link/expr.prim.lambda.closure">[expr.prim.lambda.closure]</a></span>/4:</p>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">4</a></span> The function call operator or operator template is declared <code class="sourceCode cpp"><span class="kw">const</span></code> ([class.mfct.non-static]) if and only if the <em>lambda-expression</em>’s <em>parameter-declaration-clause</em> is not followed by <code class="sourceCode cpp"><span class="kw">mutable</span></code> <span class="addu">and the <em>lambda-declarator</em> does not contain an explicit object parameter</span>.</p>
</blockquote>
<p>Change <span>7.6.1.3
 <a href="https://wg21.link/expr.call">[expr.call]</a></span>/7 to adjust the call arguments by the implied object argument:</p>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">7</a></span> When a function is called, each parameter ([dcl.fct]) is initialized ([dcl.init], [class.copy.ctor]) with its corresponding argument. <span class="addu">If the function is an explicit object member function and there is an implied object argument ([over.call.func]), the list of provided arguments is preceded by the implied object argument for the purposes of this correspondence.</span> If there is no corresponding argument, the default argument for the parameter is used. […] If the function is <span class="rm" style="color: #bf0303"><del>a non-static</del></span> <span class="addu">an implicit object</span> member function, the <code class="sourceCode cpp"><span class="kw">this</span></code> parameter of the function is initialized with a pointer to the object of the call, converted as if by an explicit type conversion. [ <em>Note</em>: There is no access or ambiguity checking on this conversion; the access checking and disambiguation are done as part of the (possibly implicit) class member access operator. See [class.member.lookup], [class.access.base], and [expr.ref]. — end note ] When a function is called, the type of any parameter shall not be a class type that is either incomplete or abstract.</p>
</blockquote>
<p>Change <span>7.6.2.2
 <a href="https://wg21.link/expr.unary.op">[expr.unary.op]</a></span>/3, requiring that taking a pointer to an explicit this function use a <em>qualified-id</em>:</p>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span> The result of the unary <code class="sourceCode cpp"><span class="op">&amp;</span></code> operator is a pointer to its operand.</p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">(3.1)</a></span> If the operand is a <em>qualified-id</em> naming a non-static or variant member <code class="sourceCode cpp">m</code> of some class <code class="sourceCode cpp">C</code> with type <code class="sourceCode cpp">T</code>, <span class="addu">other than an explicit object member function,</span> the result has type “pointer to member of class <code class="sourceCode cpp">C</code> of type <code class="sourceCode cpp">T</code>” and is a prvalue designating <code class="sourceCode cpp">C​<span class="op">::</span>​m</code>.</li>
<li><span class="marginalizedparent"><a class="marginalized">(3.2)</a></span> Otherwise, if the operand is an lvalue of type <code class="sourceCode cpp">T</code>, the resulting expression is a prvalue of type “pointer to <code class="sourceCode cpp">T</code>” whose result is a pointer to the designated object ([intro.memory]) or function. <span class="addu">If the operand names an explicit object member function (dcl.fct), the operand shall be a <em>qualified-id</em>.</span> [Note 2: In particular, taking the address of a variable of type “cv <code class="sourceCode cpp">T</code>” yields a pointer of type “pointer to cv <code class="sourceCode cpp">T</code>”. — end note]</li>
<li><span class="marginalizedparent"><a class="marginalized">(3.3)</a></span> Otherwise, the program is ill-formed.</li>
</ul>
</blockquote>
<h3 data-number="9.2.3" id="dcl.dcl"><span class="header-section-number">9.2.3</span> Wording in <span>9
 <a href="https://wg21.link/dcl.dcl">[dcl.dcl]</a></span><a href="#dcl.dcl" class="self-link"></a></h3>
<p>In <span>9.3.4.6
 <a href="https://wg21.link/dcl.fct">[dcl.fct]</a></span>/3, allow for a <em>parameter-declaration</em> to contain an optional <code class="sourceCode cpp"><span class="kw">this</span></code> keyword:</p>
<blockquote>
<blockquote>
<div class="line-block"><em>parameter-declaration-list</em>:<br />
   <em>parameter-declaration</em><br />
   <em>parameter-declaration-list</em> <code class="sourceCode cpp">,</code> <em>parameter-declaration</em><br />
</div>
</blockquote>
<blockquote>
<div class="line-block"><em>parameter-declaration</em>:<br />
   <em>attribute-specifier-seq</em><sub>opt</sub> <span class="addu"><code class="sourceCode cpp"><span class="kw">this</span></code><sub>opt</sub></span> <em>decl-specifier-seq</em> <em>declarator</em><br />
   <em>attribute-specifier-seq</em><sub>opt</sub> <span class="addu"><code class="sourceCode cpp"><span class="kw">this</span></code><sub>opt</sub></span> <em>decl-specifier-seq</em> <em>declarator</em> <code class="sourceCode cpp"><span class="op">=</span></code> <em>initializer-clause</em><br />
   <em>attribute-specifier-seq</em><sub>opt</sub> <span class="addu"><code class="sourceCode cpp"><span class="kw">this</span></code><sub>opt</sub></span> <em>decl-specifier-seq</em> <em>abstract-declarator</em><sub>opt</sub><br />
   <em>attribute-specifier-seq</em><sub>opt</sub> <span class="addu"><code class="sourceCode cpp"><span class="kw">this</span></code><sub>opt</sub></span> <em>decl-specifier-seq</em> <em>abstract-declarator</em><sub>opt</sub> <code class="sourceCode cpp"><span class="op">=</span></code> <em>initializer-clause</em></div>
</blockquote>
</blockquote>
<p>After <span>9.3.4.6
 <a href="https://wg21.link/dcl.fct">[dcl.fct]</a></span>/5, insert a paragraph describing where a function declaration with an explicit this parameter may appear, and renumber section.</p>
<blockquote>
<div class="add" style="color: #006e28">
<p><span class="marginalizedparent"><a class="marginalized">5a</a></span> An <em>explicit-object-parameter-declaration</em> is a <em>parameter-declaration</em> with a <code class="sourceCode default">this</code> specifier. An <em>explicit-object-parameter-declaration</em> shall appear only as the first <em>parameter-declaration</em> of a <em>parameter-declaration-list</em> of either:</p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">(5a.1)</a></span> a <em>member-declarator</em> that declares a member function ([class.mem]), or</li>
<li><span class="marginalizedparent"><a class="marginalized">(5a.2)</a></span> a <em>lambda-declarator</em> ([expr.prim.lambda]).</li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">5b</a></span> A <em>member-declarator</em> with an <em>explicit-object-parameter-declaration</em> shall not include a <em>ref-qualifier</em> or a <em>cv-qualifier-seq</em> and shall not be declared <code class="sourceCode default">static</code> or <code class="sourceCode default">virtual</code>.</p>
<p>[ <em>Example</em>:</p>
<div class="sourceCode" id="cb82"><pre class="sourceCode default default"><code class="sourceCode default"><span id="cb82-1"><a href="#cb82-1"></a>struct C {</span>
<span id="cb82-2"><a href="#cb82-2"></a>    void f(this C&amp; self);</span>
<span id="cb82-3"><a href="#cb82-3"></a>    template &lt;typename Self&gt;</span>
<span id="cb82-4"><a href="#cb82-4"></a>    void g(this Self&amp;&amp; self, int);</span>
<span id="cb82-5"><a href="#cb82-5"></a>    </span>
<span id="cb82-6"><a href="#cb82-6"></a>    void h(this C) const; // error: const not allowed here</span>
<span id="cb82-7"><a href="#cb82-7"></a>};</span>
<span id="cb82-8"><a href="#cb82-8"></a></span>
<span id="cb82-9"><a href="#cb82-9"></a>void test(C c) {</span>
<span id="cb82-10"><a href="#cb82-10"></a>    c.f();               // ok: calls C::f</span>
<span id="cb82-11"><a href="#cb82-11"></a>    c.g(42);             // ok: calls C::g&lt;C&amp;&gt;</span>
<span id="cb82-12"><a href="#cb82-12"></a>    std::move(c).g(42);  // ok: calls C::g&lt;C&gt;</span>
<span id="cb82-13"><a href="#cb82-13"></a>}</span></code></pre></div>
<ul>
<li><em>end example</em> ]</li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">5c</a></span> A function parameter declared with an <em>explicit-object-parameter-declaration</em> is an <em>explicit object parameter</em>. An explicit object parameter shall not be a function parameter pack ([temp.variadic]). An <em>explicit object member function</em> is a non-static member function with an explicit object parameter. An <em>implicit object member function</em> is non-static member function without an explicit object parameter.</p>
<p><span class="marginalizedparent"><a class="marginalized">5d</a></span> The <em>object parameter</em> of a non-static member function is either the explicit object parameter or the implicit object parameter ([over.match.funcs]).</p>
<p><span class="marginalizedparent"><a class="marginalized">5e</a></span> A <em>non-object parameter</em> is a function parameter that is not the explicit object parameter. The <em>non-object-parameter-type-list</em> of a member function is the parameter-type-list of that function with the explicit object parameter, if any, omitted. [ <em>Note</em>: The non-object-parameter-type-list consists of the adjusted types of all the non-object parameters. <em>-end note</em> ]</p>
</div>
</blockquote>
<p>Change <span>9.5.4
 <a href="https://wg21.link/dcl.fct.def.coroutine">[dcl.fct.def.coroutine]</a></span>/3-4:</p>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span> The <em>promise type</em> of a coroutine is <code class="sourceCode cpp">std​<span class="op">::</span>​coroutine_traits<span class="op">&lt;</span>R, P<sub>1</sub>, …, P<sub>n</sub><span class="op">&gt;</span>​<span class="op">::</span>​promise_type</code>, where <code class="sourceCode cpp">R</code> is the return type of the function, and <code class="sourceCode cpp">P<sub>1</sub>…P<sub>n</sub></code> are the sequence of types of the <span class="addu">non-object</span> function parameters, preceded by the type of the <span class="rm" style="color: #bf0303"><del>implicit</del></span> object parameter (<span class="rm" style="color: #bf0303"><del>[over.match.funcs]</del></span> <span class="addu">[dcl.fct]</span>) if the coroutine is a non-static member function. The promise type shall be a class type.</p>
<p><span class="marginalizedparent"><a class="marginalized">4</a></span> In the following, <code class="sourceCode cpp">p<sub>i</sub></code> is an lvalue of type <code class="sourceCode cpp">P<sub>i</sub></code>, where <code class="sourceCode cpp">p<sub>1</sub></code> denotes <span class="rm" style="color: #bf0303"><del><span><code class="sourceCode default">*this</code></span></del></span> <span class="addu">the object parameter</span> and <code class="sourceCode cpp">p<sub>i+1</sub></code> denotes the <em>i</em><sup>th</sup> <span class="addu">non-object</span> function parameter for a non-static member function, and <code class="sourceCode cpp">p<sub>i</sub></code> denotes the <em>i</em><sup>th</sup> function parameter otherwise.</p>
</blockquote>
<h3 data-number="9.2.4" id="wording-in-class"><span class="header-section-number">9.2.4</span> Wording in <span>11
 <a href="https://wg21.link/class">[class]</a></span><a href="#wording-in-class" class="self-link"></a></h3>
<p>Change <span>11.4.3
 <a href="https://wg21.link/class.mfct.non-static">[class.mfct.non-static]</a></span>/4-5:</p>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">4</a></span> [<em>Note 2</em>: <span class="rm" style="color: #bf0303"><del>A non-static</del></span> <span class="addu">An implicit object</span> member function can be declared with <em>cv</em>-qualifiers, which affect the type of the <code class="sourceCode cpp"><span class="kw">this</span></code> pointer ([expr.prim.this]), and/or a <em>ref-qualifier</em> ([dcl.fct]); both affect overload resolution ([over.match.funcs]) — <em>end note</em>]</p>
<p><span class="marginalizedparent"><a class="marginalized">5</a></span> <span class="rm" style="color: #bf0303"><del>A non-static</del></span> <span class="addu">An implicit object</span> member function may be declared virtual ([class.virtual]) or pure virtual ([class.abstract]).</p>
</blockquote>
<p>Change <span>11.4.8.3
 <a href="https://wg21.link/class.conv.fct">[class.conv.fct]</a></span>/1:</p>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span> A member function of a class <code class="sourceCode cpp">X</code> with a name of the form […] shall have no <span class="addu">non-object</span> parameters and specifies a conversion from <code class="sourceCode cpp">X</code> to the type specified by the <em>conversion-type-id</em>, interpreted as a <em>type-id</em> ([dcl.name]).</p>
</blockquote>
<h3 data-number="9.2.5" id="wording-in-over"><span class="header-section-number">9.2.5</span> Wording in <span>12
 <a href="https://wg21.link/over">[over]</a></span><a href="#wording-in-over" class="self-link"></a></h3>
<p>Change <span>12.2.1
 <a href="https://wg21.link/over.match.general">[over.match.general]</a></span>/;</p>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span> Overload resolution is a mechanism for selecting the best function to call given a list of expressions that are to be the arguments of the call and a set of <em>candidate functions</em> that can be called based on the context of the call. The selection criteria for the best function are the number of arguments, how well the arguments match the parameter-type-list of the candidate function, how well (for non-static member functions) the object matches the <span class="rm" style="color: #bf0303"><del>implicit</del></span> object parameter, and certain other properties of the candidate function.</p>
</blockquote>
<p>Change <span>12.2.2
 <a href="https://wg21.link/over.match.funcs">[over.match.funcs]</a></span>/2-5:</p>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span> So that argument and parameter lists are comparable within this heterogeneous set, a member function <span class="addu">that does not have an explicit object parameter</span> is considered to have an extra first parameter, called the <em>implicit object parameter</em>, which represents the object for which the member function has been called. For the purposes of overload resolution, both static and non-static member functions have an <span class="rm" style="color: #bf0303"><del>implicit</del></span> object parameter, but constructors do not.</p>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span> Similarly, when appropriate, the context can construct an argument list that contains an <em>implied object argument</em> as the first argument in the list to denote the object to be operated on.</p>
<p><span class="marginalizedparent"><a class="marginalized">4</a></span> For <span class="rm" style="color: #bf0303"><del>non-static</del></span> <span class="addu">implicit object</span> member functions, the type of the implicit object parameter is</p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">(4.1)</a></span> “lvalue reference to <em>cv</em> <code class="sourceCode cpp">X</code>” for functions declared without a <em>ref-qualifier</em> or with the <code class="sourceCode cpp"><span class="op">&amp;</span></code> <em>ref-qualifier</em></li>
<li><span class="marginalizedparent"><a class="marginalized">(4.2)</a></span> “rvalue reference to <em>cv</em> <code class="sourceCode cpp">X</code>” for functions declared with the <code class="sourceCode cpp"><span class="op">&amp;&amp;</span></code> <em>ref-qualifier</em></li>
</ul>
<p>where <code class="sourceCode cpp">X</code> is the class of which the function is a member and <em>cv</em> is the <em>cv</em>-qualification on the member function declaration. [ Example: For a <code class="sourceCode cpp"><span class="kw">const</span></code> member function of class <code class="sourceCode cpp">X</code>, the extra parameter is assumed to have type “<span class="addu">lvalue</span> reference to <code class="sourceCode cpp"><span class="kw">const</span> X</code>”. — <em>end example</em> ] For conversion functions <span class="addu">that are implicit object member functions</span>, the function is considered to be a member of the class of the implied object argument for the purpose of defining the type of the implicit object parameter. For non-conversion functions <span class="addu">that are implicit object member functions</span> introduced by a <em>using-declaration</em> into a derived class, the function is considered to be a member of the derived class for the purpose of defining the type of the implicit object parameter. For static member functions, the implicit object parameter is considered to match any object (since if the function is selected, the object is discarded). [ <em>Note</em>: No actual type is established for the implicit object parameter of a static member function, and no attempt will be made to determine a conversion sequence for that parameter ([over.match.best]). — <em>end note</em> ]</p>
<p><span class="marginalizedparent"><a class="marginalized">5</a></span> During overload resolution, the implied object argument is indistinguishable from other arguments. The implicit object parameter, however, retains its identity since no user-defined conversions can be applied to achieve a type match with it. For <span class="rm" style="color: #bf0303"><del>non-static</del></span> <span class="addu">implicit object</span> member functions declared without a <em>ref-qualifier</em>, even if the implicit object parameter is not const-qualified, an rvalue can be bound to the parameter as long as in all other respects the argument can be converted to the type of the implicit object parameter. [ <em>Note</em>: The fact that such an argument is an rvalue does not affect the ranking of implicit conversion sequences. — <em>end note</em> ]</p>
</blockquote>
<p>Add an example to <span>12.2.2.2.2
 <a href="https://wg21.link/over.call.func">[over.call.func]</a></span>/3:</p>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span> Because of the rules for name lookup, the set of candidate functions consists (1) entirely of non-member functions or (2) entirely of member functions of some class T. In case (1), the argument list is the same as the expression-list in the call. In case (2), the argument list is the <em>expression-list</em> in the call augmented by the addition of an implied object argument as in a qualified function call. If the keyword <code class="sourceCode cpp"><span class="kw">this</span></code> is in scope and refers to class <code class="sourceCode cpp">T</code>, or a derived class of <code class="sourceCode cpp">T</code>, then the implied object argument is <code class="sourceCode cpp"><span class="op">(*</span><span class="kw">this</span><span class="op">)</span></code>. If the keyword <code class="sourceCode cpp"><span class="kw">this</span></code> is not in scope or refers to another class, then a contrived object of type <code class="sourceCode cpp">T</code> becomes the implied object argument. <sup>113</sup> If the argument list is augmented by a contrived object and overload resolution selects one of the non-static member functions of <code class="sourceCode cpp">T</code>, the call is ill-formed.</p>
<div class="addu">
<p>[ <em>Example</em>:</p>
<div class="sourceCode" id="cb83"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb83-1"><a href="#cb83-1"></a>struct C {</span>
<span id="cb83-2"><a href="#cb83-2"></a>    void a();</span>
<span id="cb83-3"><a href="#cb83-3"></a>    void b() {</span>
<span id="cb83-4"><a href="#cb83-4"></a>        a(); // ok, (*this).a()</span>
<span id="cb83-5"><a href="#cb83-5"></a>    }</span>
<span id="cb83-6"><a href="#cb83-6"></a>    </span>
<span id="cb83-7"><a href="#cb83-7"></a>    void f(this const C&amp;);</span>
<span id="cb83-8"><a href="#cb83-8"></a>    void g() const {</span>
<span id="cb83-9"><a href="#cb83-9"></a>        f();       // ok: (*this).f()</span>
<span id="cb83-10"><a href="#cb83-10"></a>        f(*this);  // error: no viable candidate for (*this).f(*this)</span>
<span id="cb83-11"><a href="#cb83-11"></a>        this-&gt;f(); // ok</span>
<span id="cb83-12"><a href="#cb83-12"></a>    }</span>
<span id="cb83-13"><a href="#cb83-13"></a>    </span>
<span id="cb83-14"><a href="#cb83-14"></a>    static void h() {</span>
<span id="cb83-15"><a href="#cb83-15"></a>        f();       // error: contrived object argument, but overload resolution</span>
<span id="cb83-16"><a href="#cb83-16"></a>                   // picked a non-static member function</span>
<span id="cb83-17"><a href="#cb83-17"></a>        f(C{});    // error: no viable candidate</span>
<span id="cb83-18"><a href="#cb83-18"></a>        C{}.f();   // ok</span>
<span id="cb83-19"><a href="#cb83-19"></a>    }</span>
<span id="cb83-20"><a href="#cb83-20"></a>    </span>
<span id="cb83-21"><a href="#cb83-21"></a>    void k(this int);</span>
<span id="cb83-22"><a href="#cb83-22"></a>    operator int() const;</span>
<span id="cb83-23"><a href="#cb83-23"></a>    void m(this const C&amp; c) {</span>
<span id="cb83-24"><a href="#cb83-24"></a>        c.k();     // ok</span>
<span id="cb83-25"><a href="#cb83-25"></a>    }</span>
<span id="cb83-26"><a href="#cb83-26"></a>};</span></code></pre></div>
<ul>
<li><em>end example</em> ]</li>
</ul>
</div>
</blockquote>
<p>Change <span>12.2.2.2.3
 <a href="https://wg21.link/over.call.object">[over.call.object]</a></span>/3:</p>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span> The argument list submitted to overload resolution consists of the argument expressions present in the function call syntax preceded by the implied object argument <code class="sourceCode cpp"><span class="op">(</span>E<span class="op">)</span></code>. [ <em>Note</em>: When comparing the call against the function call operators, the implied object argument is compared against the <span class="rm" style="color: #bf0303"><del>implicit</del></span> object parameter of the function call operator. When comparing the call against a surrogate call function, the implied object argument is compared against the first parameter of the surrogate call function. The conversion function from which the surrogate call function was derived will be used in the conversion sequence for that parameter since it converts the implied object argument to the appropriate function pointer or reference required by that first parameter. — <em>end note</em> ]</p>
</blockquote>
<p>Change the note in <span>12.2.2.3
 <a href="https://wg21.link/over.match.oper">[over.match.oper]</a></span>/3.4:</p>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">(3.4.5)</a></span> [ <em>Note</em>: A candidate synthesized from a member candidate has its <span class="rm" style="color: #bf0303"><del>implicit</del></span> object parameter as the second parameter, thus implicit conversions are considered for the first, but not for the second, parameter. — <em>end note</em> ]</p>
</blockquote>
<p>Change the note in <span>12.2.2.5
 <a href="https://wg21.link/over.match.copy">[over.match.copy]</a></span>/2:</p>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span> In both cases, the argument list has one argument, which is the initializer expression. [ <em>Note</em>: This argument will be compared against the first parameter of the constructors and against the <span class="rm" style="color: #bf0303"><del>implicit</del></span> object parameter of the conversion functions. — end note ]</p>
</blockquote>
<p>Change the note in <span>12.2.2.6
 <a href="https://wg21.link/over.match.conv">[over.match.conv]</a></span>/2:</p>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span> The argument list has one argument, which is the initializer expression. [ <em>Note</em>: This argument will be compared against the <span class="rm" style="color: #bf0303"><del>implicit</del></span> object parameter of the conversion functions. — end note ]</p>
</blockquote>
<p>Change the note in <span>12.2.2.7
 <a href="https://wg21.link/over.match.ref">[over.match.ref]</a></span>/2:</p>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span> The argument list has one argument, which is the initializer expression. [ <em>Note</em>: This argument will be compared against the <span class="rm" style="color: #bf0303"><del>implicit</del></span> object parameter of the conversion functions. — end note ]</p>
</blockquote>
<p>Change <span>12.2.4.2
 <a href="https://wg21.link/over.best.ics">[over.best.ics]</a></span>/4:</p>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">4</a></span> However, if the target is</p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">(4.1)</a></span> the first parameter of a constructor or</li>
<li><span class="marginalizedparent"><a class="marginalized">(4.2)</a></span> the <span class="rm" style="color: #bf0303"><del>implicit</del></span> object parameter of a user-defined conversion function</li>
</ul>
<p>and the constructor or user-defined conversion function is a candidate by […]</p>
</blockquote>
<p>Change <span>12.2.4.2
 <a href="https://wg21.link/over.best.ics">[over.best.ics]</a></span>/7:</p>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">7</a></span> In all contexts, when converting to the implicit object parameter or when converting to the left operand of an assignment operation only standard conversion sequences are allowed. <span class="addu">[<em>Note</em>: When converting to the explicit object parameter, if any, user-defined conversion sequences are allowed. - <em>end note</em> ]</span></p>
</blockquote>
<p>Change <span>12.2.4.2.3
 <a href="https://wg21.link/over.ics.user">[over.ics.user]</a></span>/1:</p>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span> If the user-defined conversion is specified by a conversion function, the initial standard conversion sequence converts the source type to the <span class="rm" style="color: #bf0303"><del>implicit</del></span> object parameter of the conversion function.</p>
</blockquote>
<p>Change <span>12.3
 <a href="https://wg21.link/over.over">[over.over]</a></span>/4:</p>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">4</a></span> Non-member functions <span class="rm" style="color: #bf0303"><del>and</del></span><span class="addu">,</span> static member functions<span class="addu">, and explicit object member functions</span> match targets of function pointer type or reference to function type. <span class="rm" style="color: #bf0303"><del>Non-static</del></span> <span class="addu">Implicit object</span> member functions match targets of pointer-to-member-function type.</p>
<p>[<em>Note 3</em>: If <span class="rm" style="color: #bf0303"><del>a non-static</del></span> <span class="addu">an implicit object</span> member function is chosen, the result can be used only to form a pointer to member ([expr.unary.op]). — <em>end note</em>]</p>
</blockquote>
<p>Change <span>12.4
 <a href="https://wg21.link/over.oper">[over.oper]</a></span>/7:</p>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">7</a></span> An operator function shall either be a non-static member function or be a non-member function that has at least one <span class="addu">non-object</span> parameter whose type is a class, a reference to a class, an enumeration, or a reference to an enumeration.</p>
</blockquote>
<p>Change <span>12.4.2
 <a href="https://wg21.link/over.unary">[over.unary]</a></span>/1:</p>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span> A <em>prefix unary operator function</em> is a function named <code class="sourceCode cpp"><span class="kw">operator</span><span class="op">@</span></code> for a prefix <em>unary-operator</em> <code class="sourceCode cpp"><span class="op">@</span></code> ([expr.unary.op]) that is either a non-static member function ([class.mfct]) with no <span class="addu">non-object</span> parameters or a non-member function with one parameter.</p>
</blockquote>
<p>Change <span>12.4.3
 <a href="https://wg21.link/over.binary">[over.binary]</a></span>/1:</p>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span> A <em>binary operator function</em> is a function named <code class="sourceCode cpp"><span class="kw">operator</span><span class="op">@</span></code> for a binary operator <code class="sourceCode cpp"><span class="op">@</span></code> that is either a non-static member function ([class.mfct]) with one <span class="addu">non-object</span> parameter or a non-member function with two parameters.</p>
</blockquote>
<p>Change <span>12.4.5
 <a href="https://wg21.link/over.sub">[over.sub]</a></span>/1:</p>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span> A <em>subscripting operator function</em> is a function named <code class="sourceCode cpp"><span class="kw">operator</span><span class="op">[]</span></code> that is a non-static member function with exactly one <span class="addu">non-object</span> parameter.</p>
</blockquote>
<p>Change <span>12.4.6
 <a href="https://wg21.link/over.ref">[over.ref]</a></span>/1:</p>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span> A <em>class member access operator function</em> is a function named <code class="sourceCode cpp"><span class="kw">operator</span><span class="op">-&gt;</span></code> that is a non-static member function taking no <span class="addu">non-object</span> parameters.</p>
</blockquote>
<p>Change <span>12.4.7
 <a href="https://wg21.link/over.inc">[over.inc]</a></span>/1:</p>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span> An <em>increment operator function</em> is a function named <code class="sourceCode cpp"><span class="kw">operator</span><span class="op">++</span></code>. If this function is a non-static member function with no <span class="addu">non-object</span> parameters, or a non-member function with one parameter, it defines the prefix increment operator <code class="sourceCode cpp"><span class="op">++</span></code> for objects of that type. If the function is a non-static member function with one <span class="addu">non-object</span> parameter (which shall be of type <code class="sourceCode cpp"><span class="dt">int</span></code>) or a non-member function with two parameters (the second of which shall be of type <code class="sourceCode cpp"><span class="dt">int</span></code>), it defines the postfix increment operator <code class="sourceCode cpp"><span class="op">++</span></code> for objects of that type.</p>
</blockquote>
<h3 data-number="9.2.6" id="wording-in-temp"><span class="header-section-number">9.2.6</span> Wording in <span>13
 <a href="https://wg21.link/temp">[temp]</a></span><a href="#wording-in-temp" class="self-link"></a></h3>
<p>In <span>13.8.3.3
 <a href="https://wg21.link/temp.dep.expr">[temp.dep.expr]</a></span>/3, add a new kind of type dependence:</p>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span> An <em>id-expression</em> is type-dependent if it is not a concept-id and it contains</p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">(3.1)</a></span> an <em>identifier</em> associated by name lookup with one or more declarations declared with a dependent type,</li>
<li><span class="marginalizedparent"><a class="marginalized">(3.2)</a></span> an <em>identifier</em> associated by name lookup with a non-type <em>template-parameter</em> declared with a type that contains a placeholder type,</li>
<li><span class="marginalizedparent"><a class="marginalized">(3.3)</a></span> an <em>identifier</em> associated by name lookup with a variable declared with a type that contains a placeholder type ([dcl.spec.auto]) where the initializer is type-dependent,</li>
<li><span class="marginalizedparent"><a class="marginalized">(3.4)</a></span> an <em>identifier</em> associated by name lookup with one or more declarations of member functions of the current instantiation declared with a return type that contains a placeholder type,</li>
<li><span class="marginalizedparent"><a class="marginalized">(3.5)</a></span> an <em>identifier</em> associated by name lookup with a structured binding declaration whose <em>brace-or-equal-initializer</em> is type-dependent,</li>
<li><span class="marginalizedparent"><a class="marginalized">(3.5*)</a></span> <span class="addu">an <em>identifier</em> associated by name lookup with an entity captured by copy ([expr.prim.lambda.capture]) in a <em>lambda-expression</em> that has an explicit object parameter whose type is dependent ([dcl.fct]),</span></li>
<li><span class="marginalizedparent"><a class="marginalized">(3.6)</a></span> the <em>identifier</em> <code class="sourceCode cpp"><span class="ot">__func__</span></code> ([dcl.fct.def.general]), where any enclosing function is a template, a member of a class template, or a generic lambda,</li>
<li><span class="marginalizedparent"><a class="marginalized">(3.7)</a></span> a <em>template-id</em> that is dependent,</li>
<li><span class="marginalizedparent"><a class="marginalized">(3.8)</a></span> a <em>conversion-function-id</em> that specifies a dependent type, or</li>
<li><span class="marginalizedparent"><a class="marginalized">(3.9)</a></span> a <em>nested-name-specifier</em> or a <em>qualified-id</em> that names a member of an unknown specialization;</li>
</ul>
<p>or if it names a dependent member of the current instantiation that is a static data member of type “array of unknown bound of T” for some T ([temp.static]).</p>
</blockquote>
<h2 data-number="9.3" id="feature-test-macro-tabcpp.predefined.ft"><span class="header-section-number">9.3</span> Feature-test macro [tab:cpp.predefined.ft]<a href="#feature-test-macro-tabcpp.predefined.ft" class="self-link"></a></h2>
<p>Add to <span>15.11
 <a href="https://wg21.link/cpp.predefined">[cpp.predefined]</a></span>/table 17 ([tab:cpp.predefined.ft]):</p>
<p><span class="addu"><code class="sourceCode cpp">__cpp_explicit_this_parameter</code></span> with the appropriate value.</p>
<h1 data-number="10" style="border-bottom:1px solid #cccccc" id="acknowledgements"><span class="header-section-number">10</span> Acknowledgements<a href="#acknowledgements" class="self-link"></a></h1>
<p>The authors would like to thank:</p>
<ul>
<li>Jonathan Wakely, for bringing us all together by pointing out we were writing the same paper, twice</li>
<li>Chandler Carruth for a lot of feedback and guidance around many design issues, but especially for help with use cases and the pointer-types for by-value passing</li>
<li>Graham Heynes, Andrew Bennieston, Jeff Snyder for early feedback regarding the meaning of <code class="sourceCode cpp"><span class="kw">this</span></code> inside function bodies</li>
<li>Amy Worthington, Jackie Chen, Vittorio Romeo, Tristan Brindle, Agustín Bergé, Louis Dionne, and Michael Park for early feedback</li>
<li>Jens Maurer, Richard Smith, Hubert Tong, Faisal Vali, and Daveed Vandevoorde for help with wording</li>
<li>Ville Voutilainen, Herb Sutter, Titus Winters and Bjarne Stroustrup for their guidance in design-space exploration</li>
<li>Eva Conti for furious copy editing, patience, and moral support</li>
<li>Daveed Vandevoorde for his extensive feedback on recursive lambdas and implementation help</li>
</ul>
<!--
 vim: ft=markdown wrap linebreak nolist textwidth=0 wrapmargin=0
-->
<h1 data-number="11" style="border-bottom:1px solid #cccccc" id="bibliography"><span class="header-section-number">11</span> References<a href="#bibliography" class="self-link"></a></h1>
<div id="refs" class="references hanging-indent" role="doc-bibliography">
<div id="ref-Effective">
<p>[EffCpp] Scott Meyers. Effective C++, Third Edition. <br />
<a href="https://www.aristeia.com/books.html">https://www.aristeia.com/books.html</a></p>
</div>
<div id="ref-P0798R0">
<p>[P0798R0] Sy Brand. 2017-10-06. Monadic operations for std::optional. <br />
<a href="https://wg21.link/p0798r0">https://wg21.link/p0798r0</a></p>
</div>
<div id="ref-P0798R3">
<p>[P0798R3] Sy Brand. 2019-01-21. Monadic operations for std::optional. <br />
<a href="https://wg21.link/p0798r3">https://wg21.link/p0798r3</a></p>
</div>
<div id="ref-P0826R0">
<p>[P0826R0] Agustín Bergé. 2017-10-12. SFINAE-friendly std::bind. <br />
<a href="https://wg21.link/p0826r0">https://wg21.link/p0826r0</a></p>
</div>
<div id="ref-P0839R0">
<p>[P0839R0] Richard Smith. 2017-10-16. Recursive Lambdas. <br />
<a href="https://wg21.link/p0839r0">https://wg21.link/p0839r0</a></p>
</div>
<div id="ref-P0847R0">
<p>[P0847R0] Gašper Ažman, Sy Brand, Ben Deane, Barry Revzin. 2018-02-12. Deducing this. <br />
<a href="https://wg21.link/p0847r0">https://wg21.link/p0847r0</a></p>
</div>
<div id="ref-P0847R1">
<p>[P0847R1] Gašper Ažman, Sy Brand, Ben Deane, Barry Revzin. 2018-10-07. Deducing this. <br />
<a href="https://wg21.link/p0847r1">https://wg21.link/p0847r1</a></p>
</div>
<div id="ref-P0847R2">
<p>[P0847R2] Gašper Ažman, Sy Brand, Ben Deane, Barry Revzin. 2019-01-15. Deducing this. <br />
<a href="https://wg21.link/p0847r2">https://wg21.link/p0847r2</a></p>
</div>
<div id="ref-P0929R2">
<p>[P0929R2] Jens Maurer. 2018-06-06. Checking for abstract class types. <br />
<a href="https://wg21.link/p0929r2">https://wg21.link/p0929r2</a></p>
</div>
<div id="ref-P1169R0">
<p>[P1169R0] Barry Revzin, Casey Carter. 2018-10-07. static operator(). <br />
<a href="https://wg21.link/p1169r0">https://wg21.link/p1169r0</a></p>
</div>
<div id="ref-P1221R1">
<p>[P1221R1] Jason Rice. 2018-10-03. Parametric Expressions. <br />
<a href="https://wg21.link/p1221r1">https://wg21.link/p1221r1</a></p>
</div>
<div id="ref-P1787R6">
<p>[P1787R6] S. Davis Herring. 2020-10-28. Declarations and where to find them. <br />
<a href="https://wg21.link/p1787r6">https://wg21.link/p1787r6</a></p>
</div>
<div id="ref-P2237R0">
<p>[P2237R0] Andrew Sutton. 2020-10-15. Metaprogramming. <br />
<a href="https://wg21.link/p2237r0">https://wg21.link/p2237r0</a></p>
</div>
</div>
<section class="footnotes" role="doc-endnotes">
<hr />
<ol>
<li id="fn1" role="doc-endnote"><p>In the C++17 wording, we had this example <a href="https://timsong-cpp.github.io/cppwp/n4659/over.load#2.3">[over.load]/2.3 in N4659</a>:</p>
<blockquote>
<div class="sourceCode" id="cb75"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb75-1"><a href="#cb75-1"></a><span class="kw">class</span> Y <span class="op">{</span></span>
<span id="cb75-2"><a href="#cb75-2"></a>  <span class="dt">void</span> h<span class="op">()</span> <span class="op">&amp;</span>;</span>
<span id="cb75-3"><a href="#cb75-3"></a>  <span class="dt">void</span> h<span class="op">()</span> <span class="kw">const</span> <span class="op">&amp;</span>;             <span class="co">// OK</span></span>
<span id="cb75-4"><a href="#cb75-4"></a>  <span class="dt">void</span> h<span class="op">()</span> <span class="op">&amp;&amp;</span>;                  <span class="co">// OK, all declarations have a ref-qualifier</span></span>
<span id="cb75-5"><a href="#cb75-5"></a>  <span class="dt">void</span> i<span class="op">()</span> <span class="op">&amp;</span>;</span>
<span id="cb75-6"><a href="#cb75-6"></a>  <span class="dt">void</span> i<span class="op">()</span> <span class="kw">const</span>;               <span class="co">// ill-formed, prior declaration of i</span></span>
<span id="cb75-7"><a href="#cb75-7"></a>                                <span class="co">// has a ref-qualifier</span></span>
<span id="cb75-8"><a href="#cb75-8"></a><span class="op">}</span>;</span></code></pre></div>
</blockquote>
<p>The <code class="sourceCode cpp">Y<span class="op">::</span>i</code> example actually becomes well-formed after <span class="citation" data-cites="P1787R6">[<a href="#ref-P1787R6" role="doc-biblioref">P1787R6</a>]</span> (see <a href="https://lists.isocpp.org/core/2020/11/10201.php">Davis’ email to core</a>), since the prior wording did not consider <em>cv</em>-qualifiers but the new wording does. The wording change above preserves Davis’ change, the above is allowed.</p>
<p>In regards to examples like:</p>
<blockquote>
<div class="sourceCode" id="cb76"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb76-1"><a href="#cb76-1"></a><span class="kw">struct</span> A <span class="op">{</span></span>
<span id="cb76-2"><a href="#cb76-2"></a>    <span class="dt">void</span> f<span class="op">()</span>;</span>
<span id="cb76-3"><a href="#cb76-3"></a>    <span class="dt">void</span> f<span class="op">()</span> <span class="op">&amp;</span>;</span>
<span id="cb76-4"><a href="#cb76-4"></a><span class="op">}</span>;</span>
<span id="cb76-5"><a href="#cb76-5"></a></span>
<span id="cb76-6"><a href="#cb76-6"></a><span class="kw">struct</span> B <span class="op">{</span></span>
<span id="cb76-7"><a href="#cb76-7"></a>    <span class="dt">void</span> f<span class="op">()</span>;</span>
<span id="cb76-8"><a href="#cb76-8"></a>    <span class="dt">void</span> f<span class="op">()</span> <span class="op">&amp;&amp;</span>;</span>
<span id="cb76-9"><a href="#cb76-9"></a><span class="op">}</span>;</span></code></pre></div>
</blockquote>
<p>There isn’t much reason that the absence of a <em>ref-qualifier</em> is more <code class="sourceCode cpp"><span class="op">&amp;</span></code>-ish than <code class="sourceCode cpp"><span class="op">&amp;&amp;</span></code>-ish. So both of these pairs of function declarations should be rejected. It would be nice to <em>just</em> talk about the type of the object parameter, but this would only reject <code class="sourceCode cpp">A</code> but not <code class="sourceCode cpp">B</code>.</p>
<p>Hence the whole paragraph about corresponding object parameters. If exactly one is a legacy non-static member function with no <em>ref-qualifier</em>, we have to ignore the reference part of the type. That would end up with both of these corresponding.</p>
<p>For an example like this:</p>
<div class="sourceCode" id="cb77"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb77-1"><a href="#cb77-1"></a><span class="kw">struct</span> C <span class="op">{</span></span>
<span id="cb77-2"><a href="#cb77-2"></a>    <span class="dt">void</span> f<span class="op">()</span>;</span>
<span id="cb77-3"><a href="#cb77-3"></a>    <span class="dt">void</span> f<span class="op">(</span><span class="kw">this</span> C<span class="op">)</span>;</span>
<span id="cb77-4"><a href="#cb77-4"></a><span class="op">}</span>;</span></code></pre></div>
<p>This is technically differentiable by overload resolution:</p>
<div class="sourceCode" id="cb78"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb78-1"><a href="#cb78-1"></a><span class="kw">struct</span> D <span class="op">:</span> C <span class="op">{</span> <span class="op">}</span>;</span>
<span id="cb78-2"><a href="#cb78-2"></a></span>
<span id="cb78-3"><a href="#cb78-3"></a><span class="kw">const</span> C cc;</span>
<span id="cb78-4"><a href="#cb78-4"></a>cc<span class="op">.</span>f<span class="op">()</span>; <span class="co">// calls second overload</span></span>
<span id="cb78-5"><a href="#cb78-5"></a>D d;</span>
<span id="cb78-6"><a href="#cb78-6"></a>d<span class="op">.</span>f<span class="op">()</span>;  <span class="co">// calls first overload</span></span></code></pre></div>
<p>But doesn’t seem especially meaningful to support either, so should be rejected by the above rule.<a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>
</div>
</div>
</body>
</html>
