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

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

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

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

code.sourceCode > span { display: inline; }
</style>
  <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">calltarget(unevaluated-call-expression)</h1>
<table style="border:none;float:right">
  <tr>
    <td>Document #:</td>
    <td>P2825R0</td>
  </tr>
  <tr>
    <td>Date:</td>
    <td>2023-03-15</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>
    </td>
  </tr>
</table>
</header>
<div style="clear:both">
<div id="TOC" role="doc-toc">
<h1 id="toctitle">Contents</h1>
<ul>
<li><a href="#introduction" id="toc-introduction"><span class="toc-section-number">1</span> Introduction<span></span></a></li>
<li><a href="#motivation-and-prior-art" id="toc-motivation-and-prior-art"><span class="toc-section-number">2</span> Motivation and Prior
Art<span></span></a>
<ul>
<li><a href="#related-work" id="toc-related-work"><span class="toc-section-number">2.1</span> Related Work<span></span></a></li>
</ul></li>
<li><a href="#proposal" id="toc-proposal"><span class="toc-section-number">3</span> Proposal<span></span></a>
<ul>
<li><a href="#interesting-cases-in-the-above-example" id="toc-interesting-cases-in-the-above-example"><span class="toc-section-number">3.1</span> Interesting cases in the above
example<span></span></a></li>
<li><a href="#alternatives-to-syntax" id="toc-alternatives-to-syntax"><span class="toc-section-number">3.2</span> Alternatives to
syntax<span></span></a></li>
<li><a href="#naming" id="toc-naming"><span class="toc-section-number">3.3</span> Naming<span></span></a></li>
</ul></li>
<li><a href="#possible-extensions" id="toc-possible-extensions"><span class="toc-section-number">4</span> Possible Extensions<span></span></a>
<ul>
<li><a href="#inventing-contructor-free-functions" id="toc-inventing-contructor-free-functions"><span class="toc-section-number">4.1</span> Inventing contructor
free-functions<span></span></a></li>
<li><a href="#inventing-destructor-free-forms" id="toc-inventing-destructor-free-forms"><span class="toc-section-number">4.2</span> Inventing destructor
free-forms<span></span></a></li>
<li><a href="#inventing-pointers-to-built-in-functions" id="toc-inventing-pointers-to-built-in-functions"><span class="toc-section-number">4.3</span> Inventing pointers to built-in
functions<span></span></a></li>
</ul></li>
<li><a href="#usecases" id="toc-usecases"><span class="toc-section-number">5</span> Usecases<span></span></a>
<ul>
<li><a href="#what-does-this-give-us-that-we-dont-have-yet" id="toc-what-does-this-give-us-that-we-dont-have-yet"><span class="toc-section-number">5.1</span> What does this give us that we
don’t have yet<span></span></a></li>
<li><a href="#thats-not-good-enough-to-do-all-that-work.-what-else" id="toc-thats-not-good-enough-to-do-all-that-work.-what-else"><span class="toc-section-number">5.2</span> That’s not good enough to do all
that work. What else?<span></span></a></li>
</ul></li>
<li><a href="#bibliography" id="toc-bibliography"><span class="toc-section-number">6</span> References<span></span></a></li>
</ul>
</div>
<h1 data-number="1" id="introduction"><span class="header-section-number">1</span> Introduction<a href="#introduction" class="self-link"></a></h1>
<p>This paper introduces a new compile-time expression into the
language, for the moment with the syntax <code class="sourceCode default">__builtin_calltarget(<em>postfix-expression</em>)</code>.</p>
<p>The expression is a compile-time constant with the value of the
pointer-to-function (PF) or pointer-to-member-function (PMF) that
<em>would have been called</em> if the
<code class="sourceCode default"><em>postfix-expression</em></code> had
been evaluated.</p>
<p>In that, it’s basically a compile-time resolver.</p>
<h1 data-number="2" id="motivation-and-prior-art"><span class="header-section-number">2</span> Motivation and Prior Art<a href="#motivation-and-prior-art" class="self-link"></a></h1>
<p>The language already has a number of sort-of overload resolution
facilities:</p>
<ul>
<li><code class="sourceCode default">static_cast</code></li>
<li>assignment to a variable of a given function pointer type</li>
<li>function calls (implicit) - the only one that actually works</li>
</ul>
<p>All of these are woefully unsuitable for type-erasure that library
authors (such as <span class="citation" data-cites="P2300R6">[<a href="#ref-P2300R6" role="doc-biblioref">P2300R6</a>]</span>) would
actually <em>like</em> to work with. Sure, we can always indirect
through a lambda:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> R, <span class="kw">typename</span> Args<span class="op">...&gt;</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> my_erased_wrapper <span class="op">{</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">using</span> fptr <span class="op">=</span> R<span class="op">(*)(</span>Args_<span class="op">...)</span>;</span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>  fptr erased <span class="op">=</span> <span class="op">+[](</span>my_erased_wrapper<span class="op">*</span> self, <span class="kw">auto</span><span class="op">&amp;&amp;...</span> args_<span class="op">)</span> <span class="op">-&gt;</span> R <span class="op">{</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> self<span class="op">-&gt;</span>fptr<span class="op">(</span>std<span class="op">::</span>forward<span class="op">&lt;</span><span class="kw">decltype</span><span class="op">&gt;(</span>args_<span class="op">)...)</span>;</span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span>;</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
<p>This has several drawbacks:</p>
<ul>
<li>it introduces a whole new lambda scope
<ul>
<li>annoying for optimizers because extra inlining</li>
<li>annoying for debugging because of an extra stack frame</li>
</ul></li>
<li>a requirement to divine forward noexceptness by the user,</li>
<li>a requirement that arguments are <em>convertible</em> (but not
necessarily the same) as the ones the user specified in their infinite
wisdom,</li>
<li>a requirement that the return type is convertible (but not
necessarily the same) as the one the user specified in their infinite
wisdom,</li>
<li>the forward-through-a-reference inhibits copy-elision of
arguments</li>
<li>inability to flatten subsetting type-erased wrappers (we can’t
divine an exact match in the presence of overloads) (think “subsetting
vtables”)</li>
</ul>
<p>Oh, if only we had a facility to ask the compiler what function we’d
be calling and then <em>just have the pointer to it</em>.</p>
<p>This is what this paper is trying to provide.</p>
<h2 data-number="2.1" id="related-work"><span class="header-section-number">2.1</span> Related Work<a href="#related-work" class="self-link"></a></h2>
<h3 data-number="2.1.1" id="reflection"><span class="header-section-number">2.1.1</span> Reflection<a href="#reflection" class="self-link"></a></h3>
<p>Of course, reflection would give us this. However, reflection (<span class="citation" data-cites="P2320R0">[<a href="#ref-P2320R0" role="doc-biblioref">P2320R0</a>]</span>,<span class="citation" data-cites="P1240R1">[<a href="#ref-P1240R1" role="doc-biblioref">P1240R1</a>]</span>,<span class="citation" data-cites="P2237R0">[<a href="#ref-P2237R0" role="doc-biblioref">P2237R0</a>]</span>,<span class="citation" data-cites="P2087R0">[<a href="#ref-P2087R0" role="doc-biblioref">P2087R0</a>]</span>,<span class="citation" data-cites="N4856">[<a href="#ref-N4856" role="doc-biblioref">N4856</a>]</span>) is both nowhere close to
shipping, and is far wider in scope as another
<code class="sourceCode default">decltype</code>-ish proposal that’s
easily implementable today, and
<code class="sourceCode default">std::execution</code> could use
immediately.</p>
<p>Regardless of how we chose to provide this facility, it is dearly
needed, and should be provided by the standard library or a
built-in.</p>
<p>See the <a href="#alternatives-to-syntax">Alternatives to Syntax</a>
chapter for details.</p>
<h3 data-number="2.1.2" id="library-fundamentals-ts-v3"><span class="header-section-number">2.1.2</span> Library fundamentals TS v3<a href="#library-fundamentals-ts-v3" class="self-link"></a></h3>
<p>The <a href="https://cplusplus.github.io/fundamentals-ts/v3.html#meta.trans.other">Library
Fundamentals TS version 3</a> defines
<code class="sourceCode default">invocation_type&lt;F(Args...)</code>
and <code class="sourceCode default">raw_invocation_type&lt;F(Args...)&gt;</code>
with the hope of getting the function pointer type of a given call
expression.</p>
<p>However, this is not good enough to actually be able to perform that
call.</p>
<p>Observe:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> S <span class="op">{</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">static</span> <span class="dt">void</span> f<span class="op">(</span>S<span class="op">)</span> <span class="op">{}</span> <span class="co">// #1</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">void</span> f<span class="op">(</span><span class="kw">this</span> S<span class="op">)</span> <span class="op">{}</span>   <span class="co">// #2</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> h<span class="op">()</span> <span class="op">{</span></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">static_cast</span><span class="op">&lt;</span><span class="dt">void</span><span class="op">(*)(</span>S<span class="op">)&gt;(</span>S<span class="op">::</span>f<span class="op">)</span> <span class="co">// error, ambiguous</span></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>  S<span class="op">{}.</span>f<span class="op">(</span>S<span class="op">{})</span>; <span class="co">// calls #1</span></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a>  S<span class="op">{}.</span>f<span class="op">()</span>; <span class="co">// calls #2</span></span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a>  <span class="co">// no ambiguity for __builtin_calltarget</span></span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a>  <span class="fu">__builtin_calltarget</span><span class="op">(</span>S<span class="op">{}.</span>f<span class="op">(</span>S<span class="op">{}))</span>; <span class="co">// &amp;#1</span></span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a>  <span class="fu">__builtin_calltarget</span><span class="op">(</span>S<span class="op">{}.</span>f<span class="op">())</span>;    <span class="co">// &amp;#2</span></span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>A library solution can’t give us this, no matter how much we try,
unless we can reflect on unevaluated operands (which Reflection
does).</p>
<h1 data-number="3" id="proposal"><span class="header-section-number">3</span> Proposal<a href="#proposal" class="self-link"></a></h1>
<p>We propose a new (technically) non-overloadable operator (because
<code class="sourceCode default">sizeof</code> is one, and this behaves
similarly):</p>
<p>(strawman syntax)</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> fptr <span class="op">=</span> <span class="fu">__builtin_calltarget</span><span class="op">(</span><em>expression</em><span class="op">)</span>;</span></code></pre></div>
<p>Where the program is ill-formed if
<code class="sourceCode default"><em>expression</em></code> does not
call a function as its top-level AST-node (good luck to me wording
this).</p>
<p>Examples:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> g<span class="op">(</span><span class="dt">long</span> x<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> x<span class="op">+</span><span class="dv">1</span>; <span class="op">}</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> f<span class="op">()</span> <span class="op">{}</span>                                                <span class="co">// #1</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> f<span class="op">(</span><span class="dt">int</span><span class="op">)</span> <span class="op">{}</span>                                             <span class="co">// #2</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> S <span class="op">{</span></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">friend</span> <span class="kw">auto</span> <span class="kw">operator</span><span class="op">+(</span>S, S<span class="op">)</span> <span class="kw">noexcept</span> <span class="op">-&gt;</span> S <span class="op">{</span> <span class="cf">return</span> <span class="op">{}</span>; <span class="op">}</span> <span class="co">// #3</span></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">auto</span> <span class="kw">operator</span><span class="op">-(</span>S<span class="op">)</span> <span class="op">-&gt;</span> S <span class="op">{</span> <span class="cf">return</span> <span class="op">{}</span>; <span class="op">}</span>                    <span class="co">// #4</span></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a>  <span class="kw">auto</span> <span class="kw">operator</span><span class="op">-(</span>S, S<span class="op">)</span> <span class="op">-&gt;</span> S <span class="op">{</span> <span class="cf">return</span> <span class="op">{}</span>; <span class="op">}</span>                 <span class="co">// #5</span></span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a>  <span class="dt">void</span> f<span class="op">()</span> <span class="op">{}</span>                                              <span class="co">// #6</span></span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a>  <span class="dt">void</span> f<span class="op">(</span><span class="dt">int</span><span class="op">)</span> <span class="op">{}</span>                                           <span class="co">// #7</span></span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true" tabindex="-1"></a>  S<span class="op">()</span> <span class="kw">noexcept</span> <span class="op">{}</span>                                          <span class="co">// #8</span></span>
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true" tabindex="-1"></a>  <span class="op">~</span>S<span class="op">()</span> <span class="kw">noexcept</span> <span class="op">{}</span>                                         <span class="co">// #9</span></span>
<span id="cb4-12"><a href="#cb4-12" aria-hidden="true" tabindex="-1"></a>  <span class="kw">auto</span> <span class="kw">operator</span><span class="op">-&gt;(</span><span class="kw">this</span> <span class="kw">auto</span><span class="op">&amp;&amp;</span> self<span class="op">)</span> <span class="kw">const</span> <span class="op">-&gt;</span> S<span class="op">*</span>;           <span class="co">// #10</span></span>
<span id="cb4-13"><a href="#cb4-13" aria-hidden="true" tabindex="-1"></a>  <span class="kw">auto</span> <span class="kw">operator</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> i<span class="op">)</span> <span class="op">-&gt;</span> <span class="dt">int</span>;         <span class="co">// #11</span></span>
<span id="cb4-14"><a href="#cb4-14" aria-hidden="true" tabindex="-1"></a>  <span class="kw">static</span> <span class="kw">auto</span> f<span class="op">(</span>S<span class="op">)</span> <span class="op">-&gt;</span> <span class="dt">int</span>;                                 <span class="co">// #12</span></span>
<span id="cb4-15"><a href="#cb4-15" aria-hidden="true" tabindex="-1"></a>  <span class="kw">using</span> fptr <span class="op">=</span> <span class="dt">void</span><span class="op">(*)(</span><span class="dt">long</span><span class="op">)</span>;</span>
<span id="cb4-16"><a href="#cb4-16" aria-hidden="true" tabindex="-1"></a>  <span class="kw">auto</span> <span class="kw">operator</span> <span class="dt">void</span><span class="op">(*)()</span> <span class="kw">const</span> <span class="op">{</span> <span class="cf">return</span> <span class="op">&amp;</span>g; <span class="op">}</span>             <span class="co">// #13</span></span>
<span id="cb4-17"><a href="#cb4-17" aria-hidden="true" tabindex="-1"></a>  <span class="kw">auto</span> <span class="kw">operator</span><span class="op">&lt;=&gt;(</span>S <span class="kw">const</span><span class="op">&amp;)</span> <span class="op">=</span> <span class="cf">default</span>;                    <span class="co">// #14</span></span>
<span id="cb4-18"><a href="#cb4-18" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb4-19"><a href="#cb4-19" aria-hidden="true" tabindex="-1"></a>S f<span class="op">(</span><span class="dt">int</span>, <span class="dt">long</span><span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> S<span class="op">{}</span>; <span class="op">}</span>                             <span class="co">// #15</span></span>
<span id="cb4-20"><a href="#cb4-20" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> U <span class="op">:</span> S <span class="op">{}</span></span>
<span id="cb4-21"><a href="#cb4-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-22"><a href="#cb4-22" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> h<span class="op">()</span> <span class="op">{</span></span>
<span id="cb4-23"><a href="#cb4-23" aria-hidden="true" tabindex="-1"></a>  S s;</span>
<span id="cb4-24"><a href="#cb4-24" aria-hidden="true" tabindex="-1"></a>  U u;</span>
<span id="cb4-25"><a href="#cb4-25" aria-hidden="true" tabindex="-1"></a>  <span class="fu">__builtin_calltarget</span><span class="op">(</span>f<span class="op">())</span>;                     <span class="co">// ok, &amp;#1             (A)</span></span>
<span id="cb4-26"><a href="#cb4-26" aria-hidden="true" tabindex="-1"></a>  <span class="fu">__builtin_calltarget</span><span class="op">(</span>f<span class="op">(</span><span class="dv">1</span><span class="op">))</span>;                    <span class="co">// ok, &amp;#2             (B)</span></span>
<span id="cb4-27"><a href="#cb4-27" aria-hidden="true" tabindex="-1"></a>  <span class="fu">__builtin_calltarget</span><span class="op">(</span>f<span class="op">(</span>std<span class="op">::</span>declval<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;()))</span>;  <span class="co">// ok, &amp;#2             (C)</span></span>
<span id="cb4-28"><a href="#cb4-28" aria-hidden="true" tabindex="-1"></a>  <span class="fu">__builtin_calltarget</span><span class="op">(</span>f<span class="op">(</span><span class="dv">1</span><span class="bu">s</span><span class="op">))</span>;                   <span class="co">// ok, &amp;#2 (!)         (D)</span></span>
<span id="cb4-29"><a href="#cb4-29" aria-hidden="true" tabindex="-1"></a>  <span class="fu">__builtin_calltarget</span><span class="op">(</span>s <span class="op">+</span> s<span class="op">)</span>;                   <span class="co">// ok, &amp;#3             (E)</span></span>
<span id="cb4-30"><a href="#cb4-30" aria-hidden="true" tabindex="-1"></a>  <span class="fu">__builtin_calltarget</span><span class="op">(-</span>s<span class="op">)</span>;                      <span class="co">// ok, &amp;#4             (F)</span></span>
<span id="cb4-31"><a href="#cb4-31" aria-hidden="true" tabindex="-1"></a>  <span class="fu">__builtin_calltarget</span><span class="op">(-</span>u<span class="op">)</span>;                      <span class="co">// ok, &amp;#4 (!)         (G)</span></span>
<span id="cb4-32"><a href="#cb4-32" aria-hidden="true" tabindex="-1"></a>  <span class="fu">__builtin_calltarget</span><span class="op">(</span>s <span class="op">-</span> s<span class="op">)</span>;                   <span class="co">// ok, &amp;#5             (H)</span></span>
<span id="cb4-33"><a href="#cb4-33" aria-hidden="true" tabindex="-1"></a>  <span class="fu">__builtin_calltarget</span><span class="op">(</span>s<span class="op">.</span>f<span class="op">())</span>;                   <span class="co">// ok, &amp;#6             (I)</span></span>
<span id="cb4-34"><a href="#cb4-34" aria-hidden="true" tabindex="-1"></a>  <span class="fu">__builtin_calltarget</span><span class="op">(</span>u<span class="op">.</span>f<span class="op">())</span>;                   <span class="co">// ok, &amp;#6 (!)         (J)</span></span>
<span id="cb4-35"><a href="#cb4-35" aria-hidden="true" tabindex="-1"></a>  <span class="fu">__builtin_calltarget</span><span class="op">(</span>s<span class="op">.</span>f<span class="op">(</span><span class="dv">2</span><span class="op">))</span>;                  <span class="co">// ok, &amp;#7             (K)</span></span>
<span id="cb4-36"><a href="#cb4-36" aria-hidden="true" tabindex="-1"></a>  <span class="fu">__builtin_calltarget</span><span class="op">(</span>s<span class="op">)</span>;                       <span class="co">// error, constructor  (L)</span></span>
<span id="cb4-37"><a href="#cb4-37" aria-hidden="true" tabindex="-1"></a>  <span class="fu">__builtin_calltarget</span><span class="op">(</span>s<span class="op">.</span>S<span class="op">::~</span>S<span class="op">())</span>;               <span class="co">// error, destructor   (M)</span></span>
<span id="cb4-38"><a href="#cb4-38" aria-hidden="true" tabindex="-1"></a>  <span class="fu">__builtin_calltarget</span><span class="op">(</span>s<span class="op">-&gt;</span>f<span class="op">())</span>;                  <span class="co">// ok, &amp;#6 (not &amp;#10)  (N)</span></span>
<span id="cb4-39"><a href="#cb4-39" aria-hidden="true" tabindex="-1"></a>  <span class="fu">__builtin_calltarget</span><span class="op">(</span>s<span class="op">.</span>S<span class="op">::</span><span class="kw">operator</span><span class="op">-&gt;())</span>;       <span class="co">// ok, &amp;#10            (O)</span></span>
<span id="cb4-40"><a href="#cb4-40" aria-hidden="true" tabindex="-1"></a>  <span class="fu">__builtin_calltarget</span><span class="op">(</span>s<span class="op">[</span><span class="dv">1</span><span class="op">])</span>;                    <span class="co">// ok, &amp;#11            (P)</span></span>
<span id="cb4-41"><a href="#cb4-41" aria-hidden="true" tabindex="-1"></a>  <span class="fu">__builtin_calltarget</span><span class="op">(</span>S<span class="op">::</span>f<span class="op">(</span>S<span class="op">{}))</span>;               <span class="co">// ok, &amp;#12            (Q)</span></span>
<span id="cb4-42"><a href="#cb4-42" aria-hidden="true" tabindex="-1"></a>  <span class="fu">__builtin_calltarget</span><span class="op">(</span>s<span class="op">.</span>f<span class="op">(</span>S<span class="op">{}))</span>;                <span class="co">// ok, &amp;#12            (R)</span></span>
<span id="cb4-43"><a href="#cb4-43" aria-hidden="true" tabindex="-1"></a>  <span class="fu">__builtin_calltarget</span><span class="op">(</span>s<span class="op">(</span><span class="dv">1</span><span class="bu">l</span><span class="op">))</span>;                   <span class="co">// ok, &amp;#13            (S)</span></span>
<span id="cb4-44"><a href="#cb4-44" aria-hidden="true" tabindex="-1"></a>  <span class="fu">__builtin_calltarget</span><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, &amp;#15            (T)</span></span>
<span id="cb4-45"><a href="#cb4-45" aria-hidden="true" tabindex="-1"></a>  <span class="fu">__builtin_calltarget</span><span class="op">(</span><span class="kw">new</span> <span class="op">(</span><span class="kw">nullptr</span><span class="op">)</span> S<span class="op">())</span>;       <span class="co">// error, not function (U)</span></span>
<span id="cb4-46"><a href="#cb4-46" aria-hidden="true" tabindex="-1"></a>  <span class="fu">__builtin_calltarget</span><span class="op">(</span><span class="kw">delete</span> <span class="op">&amp;</span>s<span class="op">)</span>;               <span class="co">// error, not function (V)</span></span>
<span id="cb4-47"><a href="#cb4-47" aria-hidden="true" tabindex="-1"></a>  <span class="fu">__builtin_calltarget</span><span class="op">(</span><span class="dv">1</span> <span class="op">+</span> <span class="dv">1</span><span class="op">)</span>;                   <span class="co">// error, built-in     (W)</span></span>
<span id="cb4-48"><a href="#cb4-48" aria-hidden="true" tabindex="-1"></a>  <span class="fu">__builtin_calltarget</span><span class="op">([]{</span></span>
<span id="cb4-49"><a href="#cb4-49" aria-hidden="true" tabindex="-1"></a>       <span class="cf">return</span> <span class="fu">__builtin_calltarget</span><span class="op">(</span>f<span class="op">())</span>;</span>
<span id="cb4-50"><a href="#cb4-50" aria-hidden="true" tabindex="-1"></a>    <span class="op">}()())</span>;                                      <span class="co">// ok, &amp;2              (X)</span></span>
<span id="cb4-51"><a href="#cb4-51" aria-hidden="true" tabindex="-1"></a>  <span class="fu">__builtin_calltarget</span><span class="op">(</span>S<span class="op">{}</span> <span class="op">&lt;</span> S<span class="op">{})</span>;               <span class="co">// error, synthesized  (Y)</span></span>
<span id="cb4-52"><a href="#cb4-52" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<h2 data-number="3.1" id="interesting-cases-in-the-above-example"><span class="header-section-number">3.1</span> Interesting cases in the above
example<a href="#interesting-cases-in-the-above-example" class="self-link"></a></h2>
<ul>
<li>resolving different members of a free-function overload set (A, B,
C, D, T)
<ul>
<li>the (D) case is important - the
<code class="sourceCode default">short</code> argument still resolves to
the <code class="sourceCode default">int</code> overload!</li>
</ul></li>
<li>constructors and destructors (L, M, U, V) - see the <strong>possible
extensions</strong> chapter.</li>
<li>resolving different member of a member-function overload set (I, J,
K, N, Q, R)
<ul>
<li>the (J) example is important - the call on
<code class="sourceCode default">u</code> still resolves to a member
function of <code class="sourceCode default">S</code>.</li>
</ul></li>
<li>resolving built-in non-functions (W): we could make this work in a
future extension (see that chapter).</li>
<li>resolving <code class="sourceCode default">operator-&gt;</code> (N
and O). <span class="marginalizedparent"><a class="marginalized">(expr.post.general)</a></span>
specifies that
<code class="sourceCode default"><em>postfix-expression</em></code>s
group left-to-right, which means the top-most postfix-expression is the
call to <code class="sourceCode default">f()</code>, and not the
<code class="sourceCode default">-&gt;</code>. To get to
<code class="sourceCode default">S::operator-&gt;</code>, we have to ask
for it explicitly.</li>
<li>surrogate function call (S) - again, the top-most call-expression is
the function call to <code class="sourceCode default">g</code>, so that
is what is returned.</li>
<li>nested calls: (X) the top-level call is a call to a function-pointer
to #2, so that is what is returned.</li>
<li>Synthesized operators (Y) - these are not functions that we can take
pointers to, so unless we “force-manufacture” one, we can’t make this
work.</li>
</ul>
<h2 data-number="3.2" id="alternatives-to-syntax"><span class="header-section-number">3.2</span> Alternatives to syntax<a href="#alternatives-to-syntax" class="self-link"></a></h2>
<p>We could wait for reflection in which case we could write
<code class="sourceCode default">call_target</code> roughly as</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">namespace</span> std<span class="op">::</span>meta <span class="op">{</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span>info r<span class="op">&gt;</span> <span class="kw">constexpr</span> <span class="kw">auto</span> call_target <span class="op">=</span> <span class="op">[]{</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="kw">constexpr</span> <span class="op">(</span>is_nonstatic_member<span class="op">(</span>r<span class="op">))</span> <span class="op">{</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>      <span class="cf">return</span> pointer_to_member<span class="op">&lt;[:</span>pm_type_of<span class="op">(</span>r<span class="op">):]&gt;(</span>r<span class="op">)</span>;</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>      <span class="cf">return</span> entity_ref<span class="op">&lt;[:</span>type_of<span class="op">:]&gt;(</span>r<span class="op">)</span>;</span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span> <span class="co">/* insert additional cases as we define them. */</span></span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a>  <span class="op">}()</span>;</span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>And call it as</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> my_expr_ptr <span class="op">=</span> call_target<span class="op">&lt;^</span>f<span class="op">()&gt;</span>;</span></code></pre></div>
<p>It’s unlikely to be quite as efficient as just hooking directly into
the resolver, but it does have the nice property that it doesn’t take up
a whole keyword.</p>
<p>Many thanks to Daveed Vandevoorde for helping out with this
example.</p>
<h2 data-number="3.3" id="naming"><span class="header-section-number">3.3</span> Naming<a href="#naming" class="self-link"></a></h2>
<h3 data-number="3.3.1" id="grabbing-a-pattern"><span class="header-section-number">3.3.1</span> Grabbing a pattern<a href="#grabbing-a-pattern" class="self-link"></a></h3>
<p>A suggestion of an esteemed former EWG chair is that we, as a
committee, grab the keyword-space prefix
<code class="sourceCode default">__std_meta_*</code> and have all the
functions with that prefix have unevaluated arguments.</p>
<p>In that case, this proposal becomes</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a>__std_meta_calltarget<span class="op">(</span><em>unevaluated-expression</em><span class="op">)</span>;</span></code></pre></div>
<p>This is done so as to stop wringing our hands about function-like
APIs that have unevaluated operands, and going for less appropriate
solutions for want of a function. The naming itself signals that it’s
not a normal function. Its address also can’t be taken, it behaves as-if
<code class="sourceCode default">consteval</code>.</p>
<p>It’s ugly on purpose. That’s by design. It’s not meant to be
pretty.</p>
<h3 data-number="3.3.2" id="possible-names"><span class="header-section-number">3.3.2</span> Possible names<a href="#possible-names" class="self-link"></a></h3>
<p>For all intents and purposes, this facility grammatically behaves in
the same way as <code class="sourceCode default">sizeof</code>, except
that we should require the parentheses around the operand.</p>
<p>We could call it something really long and unlikely to conflict, like
<code class="sourceCode default">expression_targetof</code>, or
<code class="sourceCode default">calltargetof</code> or
<code class="sourceCode default">decltargetof</code> or
<code class="sourceCode default">targetexpr</code> or
<code class="sourceCode default">resolvetarget</code>.</p>
<h1 data-number="4" id="possible-extensions"><span class="header-section-number">4</span> Possible Extensions<a href="#possible-extensions" class="self-link"></a></h1>
<p>We could make compilers invent functions for the cases that currently
aren’t legal.</p>
<h2 data-number="4.1" id="inventing-contructor-free-functions"><span class="header-section-number">4.1</span> Inventing contructor
free-functions<a href="#inventing-contructor-free-functions" class="self-link"></a></h2>
<p>For instance, constructor calls could “invent” a free function that
is expression-equivalent to calling placement new on the return
object:</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="co">// immovable aggregate</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> my_immovable_type <span class="op">{</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>  my_other_immovable_type x;</span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>  some_immovable_type y <span class="op">=</span> <span class="op">{}</span>;</span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a>my_immovable_type x<span class="op">(</span>my_other_immovable_type<span class="op">{})</span>;</span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a><span class="co">// note: prvalue parameters in type, since in-place construction through copy-elision is possible</span></span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a>std<span class="op">::</span>same_as<span class="op">&lt;</span>my_immovable_type<span class="op">(*)(</span>my_other_immovable_type, some_immovable_type<span class="op">)&gt;</span> </span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a>  <span class="kw">auto</span> constructor_pointer <span class="op">=</span> <span class="fu">__builtin_calltarget</span><span class="op">(</span>my_immovable_type<span class="op">(</span>my_other_immovable_type<span class="op">{}))</span>;</span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> y <span class="op">=</span> constructor_pointer<span class="op">(</span>my_other_immovable_type<span class="op">{})</span>;</span>
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true" tabindex="-1"></a><span class="co">// x and y have no difference in construction.</span></span></code></pre></div>
<p>The main problem with this is that free functions have a different
ABI than constructors of aggregates - they would have to expose where to
construct the arguments in their signatures.</p>
<p>This paper is not about that, so we leave it for the future.</p>
<h2 data-number="4.2" id="inventing-destructor-free-forms"><span class="header-section-number">4.2</span> Inventing destructor
free-forms<a href="#inventing-destructor-free-forms" class="self-link"></a></h2>
<p>Or, for destructors (this would make smart pointers slightly faster
and easier to do):</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a>std<span class="op">::</span>same_as<span class="op">&lt;</span><span class="dt">void</span><span class="op">(*)(</span>S<span class="op">&amp;)&gt;</span> <span class="kw">auto</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>  dtor <span class="op">=</span> <span class="op">[](</span>S<span class="op">*</span> x<span class="op">){</span><span class="cf">return</span> <span class="fu">__builtin_calltarget</span><span class="op">(</span>x<span class="op">-&gt;~</span>S<span class="op">())</span>;<span class="op">}(</span><span class="kw">nullptr</span><span class="op">)</span>;</span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>S x;</span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>dtor<span class="op">(</span>x<span class="op">)</span>; <span class="co">// expression-equivalent to x.~S()</span></span></code></pre></div>
<h2 data-number="4.3" id="inventing-pointers-to-built-in-functions"><span class="header-section-number">4.3</span> Inventing pointers to built-in
functions<a href="#inventing-pointers-to-built-in-functions" class="self-link"></a></h2>
<p>We could invent pointers to functions that are otherwise built-in,
like built-in operators:</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="fu">__builtin_calltarget</span><span class="op">(</span><span class="dv">1</span><span class="op">+</span><span class="dv">1</span><span class="op">)</span>; <span class="co">// &amp;::operator+(int, int)</span></span></code></pre></div>
<h1 data-number="5" id="usecases"><span class="header-section-number">5</span> Usecases<a href="#usecases" class="self-link"></a></h1>
<p>Broadly, anywhere where we want to type-erase a call-expression.
Broad uses in any type-erasure library, smart pointers, ABI-stable
interfaces, compilation barriers, task-queues, runtime lifts for
double-dispatch, and the list goes on and on and on and …</p>
<h2 data-number="5.1" id="what-does-this-give-us-that-we-dont-have-yet"><span class="header-section-number">5.1</span> What does this give us that we
don’t have yet<a href="#what-does-this-give-us-that-we-dont-have-yet" class="self-link"></a></h2>
<p>Two things, mainly:</p>
<ul>
<li>no need for indirection through a lambda when resolving overlaod
sets</li>
<li>… which allows us to use copy-elision to construct function
arguments in type-erased interfaces, which is currently impossible
without accurate type information from the user.</li>
</ul>
<h2 data-number="5.2" id="thats-not-good-enough-to-do-all-that-work.-what-else"><span class="header-section-number">5.2</span> That’s not good enough to do
all that work. What else?<a href="#thats-not-good-enough-to-do-all-that-work.-what-else" class="self-link"></a></h2>
<p>Together with <span class="citation" data-cites="P2826R0">[<a href="#ref-P2826R0" role="doc-biblioref">P2826R0</a>]</span>, the two
papers constitute the ability to implement
<em>expression-equivalent</em> in many important cases (not all, that’s
probably impossible).</p>
<p><span class="citation" data-cites="P2826R0">[<a href="#ref-P2826R0" role="doc-biblioref">P2826R0</a>]</span> proposes a way for a function
signature to participate in overload resolution and, if it wins, be
replaced by some other function.</p>
<p>This facility is the key to <em>finding</em> that other function. The
ability to preserve prvalue-ness is crucial to implementing quite a lot
of the standard library customization points as mandated by the
standard, without compiler help.</p>
<h1 data-number="6" id="bibliography"><span class="header-section-number">6</span> References<a href="#bibliography" class="self-link"></a></h1>
<div id="refs" class="references csl-bib-body hanging-indent" role="doc-bibliography">
<div id="ref-N4856" class="csl-entry" role="doc-biblioentry">
[N4856] David Sankel. 2020-03-02. C++ Extensions for Reflection. <a href="https://wg21.link/n4856"><div class="csl-block">https://wg21.link/n4856</div></a>
</div>
<div id="ref-P1240R1" class="csl-entry" role="doc-biblioentry">
[P1240R1] Daveed Vandevoorde, Wyatt Childers, Andrew Sutton, Faisal
Vali, Daveed Vandevoorde. 2019-10-08. Scalable Reflection in C++. <a href="https://wg21.link/p1240r1"><div class="csl-block">https://wg21.link/p1240r1</div></a>
</div>
<div id="ref-P2087R0" class="csl-entry" role="doc-biblioentry">
[P2087R0] Mihail Naydenov. 2020-01-12. Reflection Naming: fix reflexpr.
<a href="https://wg21.link/p2087r0"><div class="csl-block">https://wg21.link/p2087r0</div></a>
</div>
<div id="ref-P2237R0" class="csl-entry" role="doc-biblioentry">
[P2237R0] Andrew Sutton. 2020-10-15. Metaprogramming. <a href="https://wg21.link/p2237r0"><div class="csl-block">https://wg21.link/p2237r0</div></a>
</div>
<div id="ref-P2300R6" class="csl-entry" role="doc-biblioentry">
[P2300R6] Michał Dominiak, Georgy Evtushenko, Lewis Baker, Lucian Radu
Teodorescu, Lee Howes, Kirk Shoop, Michael Garland, Eric Niebler, Bryce
Adelstein Lelbach. 2023-01-19. `std::execution`. <a href="https://wg21.link/p2300r6"><div class="csl-block">https://wg21.link/p2300r6</div></a>
</div>
<div id="ref-P2320R0" class="csl-entry" role="doc-biblioentry">
[P2320R0] Andrew Sutton, Wyatt Childers, Daveed Vandevoorde. 2021-02-15.
The Syntax of Static Reflection. <a href="https://wg21.link/p2320r0"><div class="csl-block">https://wg21.link/p2320r0</div></a>
</div>
<div id="ref-P2826R0" class="csl-entry" role="doc-biblioentry">
[P2826R0] Gašper Ažman. Replacement functions. <a href="https://wg21.link/P2826R0"><div class="csl-block">https://wg21.link/P2826R0</div></a>
</div>
</div>
</div>
</div>
</body>
</html>
