<!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" />
  <title>Expression Function Body</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%;}
  </style>
  <style>
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 { } /* 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 { } /* 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;
}
:not(pre) > code {
background-color: #f6f8fa;
padding: 2px 4px 2px 4px;
}
div.sourceCode {
padding: 4px;
}
blockquote {
color: #666666;
margin: 0;
padding-left: 1em;
border-left: 0.5em #f2f4f7 solid;
}
ol.enumeratea { list-style-type: none; background: inherit; }
ol.enumerate { list-style-type: none; background: inherit; }

code.sourceCode > span { display: inline; }

div#refs p { padding-left: 32px; text-indent: -32px; }
</style>
  <link href="data:image/vnd.microsoft.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">Expression Function Body</h1>

<table style="border:none;float:right">
  <tr>
    <td>Document #: </td>
    <td>xxx</td>
  </tr>
  <tr>
    <td>Date: </td>
    <td>2021-27-06</td>
  </tr>
  <tr>
    <td style="vertical-align:top">Project: </td>
    <td>Programming Language C++<br>
      SG17<br>
    </td>
  </tr>
  <tr>
    <td style="vertical-align:top">Reply-to: </td>
    <td>
      Mihail Naydenov<br>&lt;<a href="mailto:mihailnajdenov@gmail.com" class="email">mihailnajdenov@gmail.com</a>&gt;<br>
    </td>
  </tr>
</table>

</header>
<div style="clear:both">
<section id="abstract" data-number="1">
<h1 data-number="1"><span class="header-section-number">1</span> Abstract<a href="#abstract" class="self-link"></a></h1>
<p>This paper suggests a way of defining single-expression function bodies, that is aimed at solving one of the issues, which prevented standardizing the <strong>Abbreviated Lambdas<a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a></strong> proposal.</p>
</section>
<section id="background" data-number="2">
<h1 data-number="2"><span class="header-section-number">2</span> Background<a href="#background" class="self-link"></a></h1>
<section id="the-importance-of-expression-functions" data-number="2.1">
<h2 data-number="2.1"><span class="header-section-number">2.1</span> The importance of expression functions<a href="#the-importance-of-expression-functions" class="self-link"></a></h2>
<p>Both library and everyday code often require forwarding one function call to another:</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="co">// 1. Calling a member</span></span>
<span id="cb1-2"><a href="#cb1-2"></a>std<span class="op">::</span>all_of<span class="op">(</span>vs<span class="op">.</span>begin<span class="op">()</span>, vs<span class="op">.</span>end<span class="op">()</span>, <span class="op">[](</span><span class="kw">const</span> <span class="kw">auto</span><span class="op">&amp;</span> val<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> val<span class="op">.</span>check<span class="op">()</span>; <span class="op">})</span>;</span>
<span id="cb1-3"><a href="#cb1-3"></a></span>
<span id="cb1-4"><a href="#cb1-4"></a><span class="co">// 2. Binding an object</span></span>
<span id="cb1-5"><a href="#cb1-5"></a>std<span class="op">::</span>all_of<span class="op">(</span>vs<span class="op">.</span>begin<span class="op">()</span>, vs<span class="op">.</span>end<span class="op">()</span>, <span class="op">[</span>id<span class="op">](</span><span class="kw">const</span> <span class="kw">auto</span><span class="op">&amp;</span> val<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> val<span class="op">.</span>id <span class="op">==</span> id; <span class="op">})</span>;</span>
<span id="cb1-6"><a href="#cb1-6"></a></span>
<span id="cb1-7"><a href="#cb1-7"></a><span class="co">// 3. Passing a lazy argument</span></span>
<span id="cb1-8"><a href="#cb1-8"></a><span class="kw">auto</span> get_brush_or<span class="op">(</span>painter, <span class="op">[]{</span> <span class="cf">return</span> Brush<span class="op">(</span>Color<span class="op">::</span>red<span class="op">)</span>; <span class="op">})</span>;</span>
<span id="cb1-9"><a href="#cb1-9"></a></span>
<span id="cb1-10"><a href="#cb1-10"></a><span class="co">// 4. Creating an overloaded set</span></span>
<span id="cb1-11"><a href="#cb1-11"></a><span class="kw">auto</span> func<span class="op">(</span><span class="kw">const</span> std<span class="op">::</span>string<span class="op">&amp;)</span>;</span>
<span id="cb1-12"><a href="#cb1-12"></a><span class="kw">auto</span> func<span class="op">(</span><span class="dt">int</span><span class="op">)</span> <span class="kw">noexcept</span>;</span>
<span id="cb1-13"><a href="#cb1-13"></a><span class="kw">inline</span> <span class="kw">constexpr</span> <span class="kw">auto</span> func_o <span class="op">=</span> <span class="op">[](</span><span class="kw">const</span> <span class="kw">auto</span><span class="op">&amp;</span> val<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> func<span class="op">(</span>val<span class="op">)</span>; <span class="op">}</span>;</span>
<span id="cb1-14"><a href="#cb1-14"></a></span>
<span id="cb1-15"><a href="#cb1-15"></a>std<span class="op">::</span>transform<span class="op">(</span>strings<span class="op">.</span>begin<span class="op">()</span>, strings<span class="op">.</span>end<span class="op">()</span>, strings<span class="op">.</span>begin<span class="op">()</span>, func_o<span class="op">)</span>;</span>
<span id="cb1-16"><a href="#cb1-16"></a>std<span class="op">::</span>transform<span class="op">(</span>ints<span class="op">.</span>begin<span class="op">()</span>, ints<span class="op">.</span>end<span class="op">()</span>, ints<span class="op">.</span>begin<span class="op">()</span>, func_o<span class="op">)</span>;</span>
<span id="cb1-17"><a href="#cb1-17"></a></span>
<span id="cb1-18"><a href="#cb1-18"></a><span class="co">// 5. Creating an overload </span></span>
<span id="cb1-19"><a href="#cb1-19"></a><span class="kw">auto</span> pixel_at<span class="op">(</span>image<span class="op">&amp;</span> image, <span class="dt">int</span> x, <span class="dt">int</span> y<span class="op">)</span> <span class="op">{</span></span>
<span id="cb1-20"><a href="#cb1-20"></a>  <span class="cf">return</span> pixel_at<span class="op">(</span>image, point<span class="op">{</span>x, y<span class="op">})</span>;</span>
<span id="cb1-21"><a href="#cb1-21"></a><span class="op">}</span></span>
<span id="cb1-22"><a href="#cb1-22"></a></span>
<span id="cb1-23"><a href="#cb1-23"></a><span class="co">// 6. Creating a simplification wrappers</span></span>
<span id="cb1-24"><a href="#cb1-24"></a><span class="kw">auto</span> load_icon<span class="op">(</span><span class="kw">const</span> std<span class="op">::</span>string<span class="op">&amp;</span> str<span class="op">)</span> <span class="op">{</span></span>
<span id="cb1-25"><a href="#cb1-25"></a>  <span class="cf">return</span> load_resource<span class="op">(</span>resources, str, <span class="st">&quot;icn&quot;</span>, use_cache<span class="op">)</span>;</span>
<span id="cb1-26"><a href="#cb1-26"></a><span class="op">}</span></span>
<span id="cb1-27"><a href="#cb1-27"></a></span>
<span id="cb1-28"><a href="#cb1-28"></a><span class="kw">auto</span> totalDistance<span class="op">()</span> <span class="op">{</span></span>
<span id="cb1-29"><a href="#cb1-29"></a>  <span class="cf">return</span> std<span class="op">::</span>accumulate<span class="op">(</span>distSinceReset<span class="op">.</span>begin<span class="op">()</span>, distSinceReset<span class="op">.</span>end<span class="op">()</span>, distAtReset<span class="op">)</span>;</span>
<span id="cb1-30"><a href="#cb1-30"></a><span class="op">}</span></span>
<span id="cb1-31"><a href="#cb1-31"></a></span>
<span id="cb1-32"><a href="#cb1-32"></a><span class="co">// 7. Creating &quot;make&quot; functions</span></span>
<span id="cb1-33"><a href="#cb1-33"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> T, <span class="kw">class</span><span class="op">...</span> Args<span class="op">&gt;</span></span>
<span id="cb1-34"><a href="#cb1-34"></a><span class="kw">auto</span> make_the_thing<span class="op">(</span>Args<span class="op">&amp;&amp;...</span> args<span class="op">)</span> <span class="op">{</span></span>
<span id="cb1-35"><a href="#cb1-35"></a>  <span class="cf">return</span> the_thing<span class="op">&lt;</span>T, something_t<span class="op">&lt;</span>T<span class="op">&gt;&gt;(</span>std<span class="op">::</span>forward<span class="op">&lt;</span>Args<span class="op">&gt;(</span>args<span class="op">)...)</span>;</span>
<span id="cb1-36"><a href="#cb1-36"></a><span class="op">}</span></span>
<span id="cb1-37"><a href="#cb1-37"></a></span>
<span id="cb1-38"><a href="#cb1-38"></a><span class="co">// 8. Creating operator implementations</span></span>
<span id="cb1-39"><a href="#cb1-39"></a><span class="kw">auto</span> <span class="kw">operator</span><span class="op">==(</span><span class="kw">const</span> A<span class="op">&amp;</span> a, <span class="kw">const</span> B<span class="op">&amp;</span> b<span class="op">)</span> <span class="op">{</span></span>
<span id="cb1-40"><a href="#cb1-40"></a>  <span class="cf">return</span> a<span class="op">.</span>id <span class="op">==</span> b<span class="op">.</span>key<span class="op">()</span>;</span>
<span id="cb1-41"><a href="#cb1-41"></a><span class="op">}</span></span>
<span id="cb1-42"><a href="#cb1-42"></a></span>
<span id="cb1-43"><a href="#cb1-43"></a>basic_string<span class="op">&amp;</span> basic_string<span class="op">::</span><span class="kw">operator</span><span class="op">=(</span><span class="kw">const</span> Char<span class="op">*</span> s<span class="op">)</span> <span class="op">{</span></span>
<span id="cb1-44"><a href="#cb1-44"></a>  <span class="cf">return</span> <span class="kw">this</span><span class="op">-&gt;</span>assign<span class="op">(</span>s<span class="op">)</span>;</span>
<span id="cb1-45"><a href="#cb1-45"></a><span class="op">}</span></span>
<span id="cb1-46"><a href="#cb1-46"></a></span>
<span id="cb1-47"><a href="#cb1-47"></a><span class="co">// 9. Creating functions delegating to other functions</span></span>
<span id="cb1-48"><a href="#cb1-48"></a><span class="kw">class</span> Person</span>
<span id="cb1-49"><a href="#cb1-49"></a><span class="op">{</span></span>
<span id="cb1-50"><a href="#cb1-50"></a><span class="kw">public</span><span class="op">:</span></span>
<span id="cb1-51"><a href="#cb1-51"></a>  <span class="kw">auto</span> name<span class="op">()</span> <span class="kw">const</span> <span class="op">{</span> <span class="cf">return</span> id<span class="op">.</span>name<span class="op">()</span>; <span class="op">}</span></span>
<span id="cb1-52"><a href="#cb1-52"></a>  <span class="dt">void</span> setName<span class="op">(</span><span class="kw">const</span> std<span class="op">::</span>string<span class="op">&amp;</span> val<span class="op">)</span> <span class="op">{</span> id<span class="op">.</span>setName<span class="op">(</span>val<span class="op">)</span>; <span class="op">}</span></span>
<span id="cb1-53"><a href="#cb1-53"></a>  <span class="op">...</span></span>
<span id="cb1-54"><a href="#cb1-54"></a><span class="kw">private</span><span class="op">:</span></span>
<span id="cb1-55"><a href="#cb1-55"></a>  Identity id;</span>
<span id="cb1-56"><a href="#cb1-56"></a>  <span class="op">...</span></span>
<span id="cb1-57"><a href="#cb1-57"></a><span class="op">}</span>;</span>
<span id="cb1-58"><a href="#cb1-58"></a></span>
<span id="cb1-59"><a href="#cb1-59"></a><span class="co">// 10. Creating generic forwarding objects</span></span>
<span id="cb1-60"><a href="#cb1-60"></a><span class="kw">auto</span> repack<span class="op">(</span><span class="kw">auto</span> a<span class="op">)</span> <span class="op">{</span></span>
<span id="cb1-61"><a href="#cb1-61"></a>  <span class="kw">auto</span> b <span class="op">=</span> <span class="op">...</span>;</span>
<span id="cb1-62"><a href="#cb1-62"></a>  <span class="cf">return</span> <span class="op">[</span>a,b<span class="op">]&lt;</span><span class="kw">class</span><span class="op">...</span> T<span class="op">&gt;(</span>T<span class="op">&amp;&amp;...</span> args<span class="op">)</span> <span class="kw">mutable</span> <span class="op">{</span> <span class="cf">return</span> a<span class="op">.</span>eval<span class="op">(</span>b, std<span class="op">::</span>forward<span class="op">&lt;</span>T<span class="op">&gt;</span>args<span class="op">...)</span>; <span class="op">}</span></span>
<span id="cb1-63"><a href="#cb1-63"></a><span class="op">}</span></span></code></pre></div>
<p>As you can see, the list is fairly long, and surely incomplete (we can add deprecating functions, wrapping C-style API create/release calls, etc), yet none of the examples are obscure, quite the contrary, this is code that exists in literally very codebase.</p>
<blockquote>
<p>Also note, normal functions do forwarding not less often the lambdas!</p>
</blockquote>
<p>All of these examples however are incorrect and most of them are suboptimal. They are incorrect because they override the exceptions specifiers in all calls and are suboptimal when concepts/SFINAE checks are required. For details see the original P0573R2<a href="#fn2" class="footnote-ref" id="fnref2" role="doc-noteref"><sup>2</sup></a> proposal.</p>
<p>These two problems are fundamental and although they could be solved via extreme verbosity and/or macros, this is not a practical solution in most cases. At this point, to go to the effort, “to do it right”, is something only library writers will do (and suffer the pain).</p>
<p>We can do a better job. This was the main motivation behind P0573R2<a href="#fn3" class="footnote-ref" id="fnref3" role="doc-noteref"><sup>3</sup></a>, and this is the main motivation of the current paper as well - <em><strong>allow correct and optimal code by default</strong></em>. It is not just about saving few characters.</p>
<p>Interestingly both of the issues seem to get more pronounced over time. Modern concept-based code brings “SFINAE to the masses” - now <em>anyone</em> can write a function, overloaded by a type constrain:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb2-1"><a href="#cb2-1"></a><span class="dt">void</span> something<span class="op">(</span>std<span class="op">::</span>invocable<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;</span> <span class="kw">auto</span> f<span class="op">)</span>;</span>
<span id="cb2-2"><a href="#cb2-2"></a><span class="dt">void</span> something<span class="op">(</span>std<span class="op">::</span>invocable<span class="op">&lt;</span>std<span class="op">::</span>string<span class="op">&gt;</span> <span class="kw">auto</span> f<span class="op">)</span>;</span></code></pre></div>
<p>Yet, calling this with our current “no-brainer” lambda will fail:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb3-1"><a href="#cb3-1"></a>something<span class="op">([](</span><span class="kw">auto</span> arg<span class="op">){</span> <span class="cf">return</span> arg<span class="op">/</span><span class="dv">2</span>; <span class="op">})</span></span></code></pre></div>
<p>This is just one example, but we can expect, the amount of code requiring concepts/SFINAE checks to rise, <em>often even without the author of the original code realizing it completely</em> - it comes naturally. To have things “just work” is now of greater value then ever, as checks like this are no longer in “expert”, “template magic” code, they will be everywhere.</p>
<p>Arguably, with the exception specifiers, things can get even more interesting, with the push for the new “value-based” exceptions<a href="#fn4" class="footnote-ref" id="fnref4" role="doc-noteref"><sup>4</sup></a>:</p>
<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">auto</span> func<span class="op">(</span><span class="kw">const</span> std<span class="op">::</span>string<span class="op">&amp;)</span> throws; <span class="co">//&lt; updated to throw statically!</span></span>
<span id="cb4-2"><a href="#cb4-2"></a><span class="kw">auto</span> func<span class="op">(</span><span class="dt">int</span><span class="op">)</span>;</span>
<span id="cb4-3"><a href="#cb4-3"></a><span class="op">...</span></span>
<span id="cb4-4"><a href="#cb4-4"></a>std<span class="op">::</span>transform<span class="op">(</span>vs<span class="op">.</span>begin<span class="op">()</span>, vs<span class="op">.</span>end<span class="op">()</span>, vs<span class="op">.</span>begin<span class="op">()</span>, <span class="op">[](</span><span class="kw">const</span> <span class="kw">auto</span><span class="op">&amp;</span> val<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> func<span class="op">(</span>val<span class="op">)</span>; <span class="op">})</span>; <span class="co">//&lt; What will happen here?!?</span></span></code></pre></div>
<p>In the above code, the original functions switched to static expression. What happens to the lambda? According to the current proposal - it will still use dynamic exceptions, transforming the static to a dynamic one. <strong>Definitely</strong> not what the user had hoped for!</p>
<blockquote>
<p>Another topic to consider are “niebloids”/CPO/CPF. We can speculate, these will have an elaborate implementation somewhere and the CPO will only delegate/forward to it. For CPO both exception specification and especially the concept checks are essential.</p>
</blockquote>
</section>
<section id="abbreviated-lambdas" data-number="2.2">
<h2 data-number="2.2"><span class="header-section-number">2.2</span> Abbreviated Lambdas<a href="#abbreviated-lambdas" class="self-link"></a></h2>
<p><strong>Abbreviated Lambdas</strong><a href="#fn5" class="footnote-ref" id="fnref5" role="doc-noteref"><sup>5</sup></a> is a proposal which aimed to solve the above issues. It was rejected for the following reasons:<a href="#fn6" class="footnote-ref" id="fnref6" role="doc-noteref"><sup>6</sup></a></p>
<ul>
<li><strong>Differing semantics with regular lambdas.</strong> Means that the same function body will return different types, depending if it as an abbreviated lambda or normal one.<br />
</li>
<li><strong>Arbitrary lookahead parsing.</strong> Means the parser must skip up to the beginning of the body of the lambda to know if it deals with omitted types or not.<br />
</li>
<li><strong>Mismatch between the trailing-return-type and the body</strong> As the name suggests, the return type and the body are parsed differently, making the Abbreviated Lambdas might fail to perform as intended.</li>
</ul>
<p>The last issue will be addressed by <strong>p2036r1</strong><a href="#fn7" class="footnote-ref" id="fnref7" role="doc-noteref"><sup>7</sup></a>.<br />
The second issue will be addressed by a separate <strong>P2425R0</strong> <strong>Abbreviated Parameters</strong> proposal .</p>
<p>The current proposal attempts to solve the first issue: <strong>Differing semantics with regular lambdas.</strong></p>
</section>
<section id="what-was-the-issue-again" data-number="2.3">
<h2 data-number="2.3"><span class="header-section-number">2.3</span> What was the issue again?<a href="#what-was-the-issue-again" class="self-link"></a></h2>
<p><strong>Abbreviated Lambdas</strong> were defined as follows:</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="op">[]()</span> <span class="kw">noexcept</span><span class="op">(</span><span class="kw">noexcept</span><span class="op">(</span>_expression_<span class="op">))</span> <span class="op">-&gt;</span> <span class="kw">decltype</span><span class="op">((</span>_expression_<span class="op">))</span> <span class="op">{</span> <span class="cf">return</span> _expression_; <span class="op">}</span>;</span></code></pre></div>
<p>This means that reference-semantics are the default:</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="co">// given</span></span>
<span id="cb6-2"><a href="#cb6-2"></a><span class="dt">int</span> i;</span>
<span id="cb6-3"><a href="#cb6-3"></a><span class="kw">auto</span> l <span class="op">=</span> <span class="op">[](</span><span class="dt">int</span><span class="op">*</span> p<span class="op">)</span> <span class="kw">noexcept</span><span class="op">(</span><span class="kw">noexcept</span><span class="op">(*</span>p<span class="op">))</span> <span class="op">-&gt;</span> <span class="kw">decltype</span><span class="op">((*</span>p<span class="op">))</span> <span class="op">{</span> <span class="cf">return</span> <span class="op">*</span>p; <span class="op">}</span>;</span>
<span id="cb6-4"><a href="#cb6-4"></a></span>
<span id="cb6-5"><a href="#cb6-5"></a><span class="co">// decltype(l(&amp;i)) is int&amp;</span></span>
<span id="cb6-6"><a href="#cb6-6"></a></span>
<span id="cb6-7"><a href="#cb6-7"></a><span class="co">// where by default</span></span>
<span id="cb6-8"><a href="#cb6-8"></a></span>
<span id="cb6-9"><a href="#cb6-9"></a><span class="kw">auto</span> l2 <span class="op">=</span> <span class="op">[](</span><span class="dt">int</span><span class="op">*</span> p<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> <span class="op">*</span>p; <span class="op">}</span></span>
<span id="cb6-10"><a href="#cb6-10"></a><span class="kw">auto</span> func<span class="op">(</span><span class="dt">int</span><span class="op">*)</span> <span class="op">{</span> <span class="cf">return</span> <span class="op">*</span>p; <span class="op">}</span></span>
<span id="cb6-11"><a href="#cb6-11"></a></span>
<span id="cb6-12"><a href="#cb6-12"></a><span class="co">// decltype(l2(&amp;i)) and decltype(func(&amp;i)) are int</span></span></code></pre></div>
<p>Effectively, if the user want to use an abbreviated form, <code>[](int* p) =&gt; *p;</code> in place of <code>[](int* p) { return *p; }</code>, he/she will get a different result.<br />
Sometimes the results can unexpectedly different:</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="op">[](</span><span class="kw">auto</span> val<span class="op">)</span> <span class="op">=&gt;</span> val;</span></code></pre></div>
<p><em>The above will return reference to local.</em> Probably not great and not what the user expects. Granted, any compiler on the planet will warn when that happens. Of course returning a reference is often (arguably more often) the desired behavior, including in the pointer example above:</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb8-1"><a href="#cb8-1"></a><span class="dt">int</span> i;</span>
<span id="cb8-2"><a href="#cb8-2"></a><span class="kw">auto</span> lp <span class="op">=</span> <span class="op">[](</span><span class="dt">int</span><span class="op">*</span> p<span class="op">)</span> <span class="op">=&gt;</span> <span class="op">*</span>p; </span>
<span id="cb8-3"><a href="#cb8-3"></a></span>
<span id="cb8-4"><a href="#cb8-4"></a><span class="dt">int</span><span class="op">*</span> p <span class="op">=</span> <span class="op">&amp;</span>i;</span>
<span id="cb8-5"><a href="#cb8-5"></a></span>
<span id="cb8-6"><a href="#cb8-6"></a>lp<span class="op">(&amp;</span>i<span class="op">)</span> <span class="op">=</span> <span class="dv">10</span>; </span>
<span id="cb8-7"><a href="#cb8-7"></a><span class="op">*</span>p <span class="op">+=</span> <span class="dv">10</span>;    </span>
<span id="cb8-8"><a href="#cb8-8"></a></span>
<span id="cb8-9"><a href="#cb8-9"></a><span class="co">// i == 20</span></span></code></pre></div>
<p><em>The lambda behaves “as-if” we used a pointer directly.</em></p>
</section>
</section>
<section id="proposal" data-number="3">
<h1 data-number="3"><span class="header-section-number">3</span> Proposal<a href="#proposal" class="self-link"></a></h1>
<p>Current proposal presents two variants for mitigating the above issue. Mitigating because there is no problem to fix - different semantics are good for different situations. The two alternative are split on what should be the default in minimal expression form.</p>
<ul>
<li><strong>Variant One</strong> will argue, the minimal expression should have reference semantics, but a non-minimal expression will have value-semantics. <em>This is the main proposal.</em></li>
<li><strong>Variant Two</strong> will present an option where minimal expression yields value semantics and reference semantics are an “opt-in”.</li>
</ul>
<section id="variant-one-proposed" data-number="3.1">
<h2 data-number="3.1"><span class="header-section-number">3.1</span> Variant One (proposed)<a href="#variant-one-proposed" class="self-link"></a></h2>
<p>This variant envisions “in-between” expression, where the user will get all the benefits of the function body being and expression (exception specifiers, concept/SFINAE friendliness) while still having the value-semantics like normal functions.<br />
This “in-between” expression is achieved simply by removing the curly brackets around an normal, single expression function body with deduced return type:</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb9-1"><a href="#cb9-1"></a><span class="co">// From</span></span>
<span id="cb9-2"><a href="#cb9-2"></a><span class="kw">auto</span> pixel_at<span class="op">(</span>image<span class="op">&amp;</span> image, <span class="dt">int</span> x, <span class="dt">int</span> y<span class="op">)</span> <span class="op">{</span></span>
<span id="cb9-3"><a href="#cb9-3"></a>  <span class="cf">return</span> pixel_at<span class="op">(</span>image, point<span class="op">{</span>x, y<span class="op">})</span>;</span>
<span id="cb9-4"><a href="#cb9-4"></a><span class="op">}</span></span>
<span id="cb9-5"><a href="#cb9-5"></a><span class="co">// To (this proposal)</span></span>
<span id="cb9-6"><a href="#cb9-6"></a><span class="kw">auto</span> pixel_at<span class="op">(</span>image<span class="op">&amp;</span> image, <span class="dt">int</span> x, <span class="dt">int</span> y<span class="op">)</span> <span class="co">//&lt; no curly braces</span></span>
<span id="cb9-7"><a href="#cb9-7"></a>  <span class="cf">return</span> pixel_at<span class="op">(</span>image, point<span class="op">{</span>x, y<span class="op">})</span>;</span></code></pre></div>
<p>The above will be equivalent to:</p>
<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">auto</span> pixel_at<span class="op">(</span>image<span class="op">&amp;</span> image, <span class="dt">int</span> x, <span class="dt">int</span> y<span class="op">)</span> </span>
<span id="cb10-2"><a href="#cb10-2"></a>  <span class="kw">noexcept</span><span class="op">(</span><span class="kw">noexcept</span><span class="op">(</span>std<span class="op">::</span>decay_t<span class="op">&lt;</span><span class="kw">decltype</span><span class="op">(</span>pixel_at<span class="op">(</span>image, point<span class="op">{</span>x, y<span class="op">}))&gt;(</span>pixel_at<span class="op">(</span>image, point<span class="op">{</span>x, y<span class="op">}))))</span></span>
<span id="cb10-3"><a href="#cb10-3"></a>  <span class="op">-&gt;</span> <span class="kw">decltype</span><span class="op">((</span>std<span class="op">::</span>decay_t<span class="op">&lt;</span><span class="kw">decltype</span><span class="op">(</span>pixel_at<span class="op">(</span>image, point<span class="op">{</span>x, y<span class="op">}))&gt;(</span>pixel_at<span class="op">(</span>image, point<span class="op">{</span>x, y<span class="op">}))))</span> </span>
<span id="cb10-4"><a href="#cb10-4"></a>    <span class="op">{</span> <span class="cf">return</span> pixel_at<span class="op">(</span>image, point<span class="op">{</span>x, y<span class="op">})</span>; <span class="op">}</span></span></code></pre></div>
<p>In other words, the behavior regarding the return type is still the same, but with added benefits of exception correctness and concept/SFINAE friendliness.<br />
For example, if the original <code>pixel_at</code> returned a reference to the pixel, moving to expression form will not change the behavior and the overload will still return a value. Because overloads returning different types in this way is not realistic, let’s change the example a bit:</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="co">// given</span></span>
<span id="cb11-2"><a href="#cb11-2"></a><span class="kw">const</span> pixel<span class="op">&amp;</span> pixel_ref_at<span class="op">(</span><span class="kw">const</span> image<span class="op">&amp;</span> image, point p<span class="op">)</span> <span class="kw">noexcept</span>;</span>
<span id="cb11-3"><a href="#cb11-3"></a><span class="co">// From</span></span>
<span id="cb11-4"><a href="#cb11-4"></a><span class="kw">auto</span> pixel_at<span class="op">(</span><span class="kw">const</span> image<span class="op">&amp;</span> image, <span class="dt">int</span> x, <span class="dt">int</span> y<span class="op">)</span> <span class="op">{</span></span>
<span id="cb11-5"><a href="#cb11-5"></a>  <span class="cf">return</span> pixel_ref_at<span class="op">(</span>image, point<span class="op">{</span>x, y<span class="op">})</span>;</span>
<span id="cb11-6"><a href="#cb11-6"></a><span class="op">}</span></span>
<span id="cb11-7"><a href="#cb11-7"></a><span class="co">// To (this proposal)</span></span>
<span id="cb11-8"><a href="#cb11-8"></a><span class="kw">auto</span> pixel_at<span class="op">(</span><span class="kw">const</span> image<span class="op">&amp;</span> image, <span class="dt">int</span> x, <span class="dt">int</span> y<span class="op">)</span> </span>
<span id="cb11-9"><a href="#cb11-9"></a>  <span class="cf">return</span> pixel_ref_at<span class="op">(</span>image, point<span class="op">{</span>x, y<span class="op">})</span>;</span></code></pre></div>
<p>After transformation, the new code still returns a pixel by value, but is now also correctly decorated as <code>noexcept</code> (if <code>pixel</code> is <code>noexcept</code> copyable as well).<br />
Preserving the <code>return</code> acts as an indicator, one is still in the “function land”, where we <em>call</em> and <em>return</em>:</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">auto</span> l <span class="op">=</span> <span class="op">[](</span><span class="kw">auto</span> val<span class="op">)</span> <span class="cf">return</span> val;</span>
<span id="cb12-2"><a href="#cb12-2"></a></span>
<span id="cb12-3"><a href="#cb12-3"></a><span class="co">// _return_ by value</span></span>
<span id="cb12-4"><a href="#cb12-4"></a><span class="co">// decltype(l(1)) is int</span></span></code></pre></div>
<p>The above clearly express the notion of passing the value along to whoever called the lambda. The argument is taken, then a value is <em>returned</em> back:</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="dt">int</span> i;</span>
<span id="cb13-2"><a href="#cb13-2"></a><span class="kw">auto</span> l <span class="op">=</span> <span class="op">[](</span><span class="kw">auto</span><span class="op">*</span> p<span class="op">)</span> <span class="cf">return</span> <span class="op">*</span>p; </span>
<span id="cb13-3"><a href="#cb13-3"></a></span>
<span id="cb13-4"><a href="#cb13-4"></a><span class="co">// _return_ the result of dereference</span></span>
<span id="cb13-5"><a href="#cb13-5"></a><span class="co">// decltype(l(&amp;i)) is int</span></span></code></pre></div>
<section id="complete-expression-function" data-number="3.1.1">
<h3 data-number="3.1.1"><span class="header-section-number">3.1.1</span> complete expression function<a href="#complete-expression-function" class="self-link"></a></h3>
<p>When we want full “expression functions”, we go one step further, away from normal functions, by dropping the <code>return</code> as well:</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">auto</span> l <span class="op">=</span> <span class="op">[](</span><span class="kw">auto</span><span class="op">*</span> p<span class="op">)</span> <span class="op">*</span>p; </span>
<span id="cb14-2"><a href="#cb14-2"></a></span>
<span id="cb14-3"><a href="#cb14-3"></a><span class="co">// equivalent of </span></span>
<span id="cb14-4"><a href="#cb14-4"></a><span class="kw">auto</span> l <span class="op">=</span> <span class="op">[](</span><span class="kw">auto</span><span class="op">*</span> p<span class="op">)</span> <span class="kw">noexcept</span><span class="op">(</span><span class="kw">noexcept</span><span class="op">(*</span>p<span class="op">))</span> <span class="op">-&gt;</span> <span class="kw">decltype</span><span class="op">((*</span>p<span class="op">))</span> <span class="op">{</span> <span class="cf">return</span> <span class="op">*</span>p; <span class="op">}</span>;</span></code></pre></div>
<p>The result is “as-if” the dereference was done in the scope that uses the lambda:</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="dt">int</span> i;</span>
<span id="cb15-2"><a href="#cb15-2"></a><span class="kw">auto</span> l <span class="op">=</span> <span class="op">[](</span><span class="kw">auto</span><span class="op">*</span> p<span class="op">)</span> <span class="op">*</span>p; </span>
<span id="cb15-3"><a href="#cb15-3"></a><span class="dt">int</span><span class="op">*</span> p <span class="op">=</span> <span class="op">&amp;</span>i;</span>
<span id="cb15-4"><a href="#cb15-4"></a></span>
<span id="cb15-5"><a href="#cb15-5"></a><span class="co">// decltype(l(&amp;i)) == decltype(*p)</span></span></code></pre></div>
<p>This behavior is as <strong>Abbreviated Lambdas</strong> originally proposed.</p>
</section>
<section id="motivation" data-number="3.1.2">
<h3 data-number="3.1.2"><span class="header-section-number">3.1.2</span> Motivation<a href="#motivation" class="self-link"></a></h3>
<p>The goal of the proposed solution is twofold:</p>
<ul>
<li>Create a “layered” approach, where one has gradual transition b/w ordinary functions and “expression functions”.</li>
<li>Represent the “pure expression” form as closely as possible to “just an expression” with as less syntactical “hints” as possible.</li>
</ul>
<p>The first goal is achieved by preserving the <code>return</code> keyword like a normal function. The <code>return</code> serves as a “safety net” against possible surprizes as it <em>looks</em> familiar and it makes the expression <em>act</em> familiar. In a way, <code>return</code> gets you <em>back</em> to normal function behavior, where an effort is needed to actually return a reference.</p>
<blockquote>
<p>It is worth stressing out, the situations where <code>return</code> is <em>actually needed</em> are rare. Vast majority of cases both expressions will behave the same and often even return the same thing. <code>return</code> will only be needed <em>to prevent</em> returning a reference, not so much <em>enabling</em> returning a value - <code>[](auto&amp; i) i+1;</code> still returns a value.</p>
</blockquote>
<p>The second goal’s motivation is to get to the actual expression as close as possible, distancing ourselves from the function metaphor where the body “returns” a value. This is the reason why the <code>=&gt;</code> is not used - it is ultimately a different spelling for “a return”, and also an evolution of <code>-&gt;</code>. Where <code>-&gt;</code> indicates “return type”, <code>=&gt;</code> indicates “return the expression”. The strong notion of returning something is what we try to avoid here. We want a new construct, distant from normal functions and expectations how they work. Take the most simple expression an example:</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="dv">1</span>;</span>
<span id="cb16-2"><a href="#cb16-2"></a><span class="op">^~~~</span> expression</span></code></pre></div>
<p>We want to <em>lift</em> that into a construct that will be (re)used at later time. Luckily, we already have distinct lambda introducing syntax. We can use it here without additional syntactical burden (in most cases anyway):</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">auto</span> l <span class="op">=</span> <span class="op">[]</span> <span class="dv">1</span>;</span>
<span id="cb17-2"><a href="#cb17-2"></a>         <span class="op">~~^~~</span> <span class="st">&quot;reusable expression&quot;</span></span>
<span id="cb17-3"><a href="#cb17-3"></a><span class="kw">auto</span> b <span class="op">=</span> l<span class="op">()</span>;</span>
<span id="cb17-4"><a href="#cb17-4"></a>         <span class="op">~~^~~</span> <span class="st">&quot;reuse&quot;</span></span>
<span id="cb17-5"><a href="#cb17-5"></a>         </span>
<span id="cb17-6"><a href="#cb17-6"></a><span class="co">// more examples</span></span>
<span id="cb17-7"><a href="#cb17-7"></a><span class="op">[]</span> <span class="op">::</span>value;</span>
<span id="cb17-8"><a href="#cb17-8"></a><span class="op">[]</span> func<span class="op">()</span>;</span>
<span id="cb17-9"><a href="#cb17-9"></a><span class="op">[</span>s<span class="op">]</span> s<span class="op">.</span>member<span class="op">()</span>;</span></code></pre></div>
<p>This paper argues, the above expressions are significantly different then a function to command different understanding. To the very least, it is much less likely, someone will be surprized, that this works:</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">auto</span> l <span class="op">=</span> <span class="op">[]</span> <span class="op">::</span>value;</span>
<span id="cb18-2"><a href="#cb18-2"></a></span>
<span id="cb18-3"><a href="#cb18-3"></a>l<span class="op">()</span> <span class="op">=</span> <span class="dv">10</span>;</span>
<span id="cb18-4"><a href="#cb18-4"></a></span>
<span id="cb18-5"><a href="#cb18-5"></a><span class="co">// ::value == 10</span></span></code></pre></div>
<p>or this</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="dt">int</span> i <span class="op">=</span> <span class="dv">2</span>;</span>
<span id="cb19-2"><a href="#cb19-2"></a><span class="kw">auto</span> l <span class="op">=</span> <span class="op">[](</span><span class="dt">int</span><span class="op">&amp;</span> i<span class="op">)</span> i<span class="op">+=</span><span class="dv">2</span>;</span>
<span id="cb19-3"><a href="#cb19-3"></a></span>
<span id="cb19-4"><a href="#cb19-4"></a>l<span class="op">(</span><span class="dv">12</span><span class="op">)/</span><span class="dv">2</span>;</span>
<span id="cb19-5"><a href="#cb19-5"></a></span>
<span id="cb19-6"><a href="#cb19-6"></a><span class="co">// i == 2;</span></span></code></pre></div>
<p>Once reference semantics mindset is establish, people will not confused or have the wrong expectations. Users will know from experience, the expression <em>always</em> yields a reference, <em>if</em> there is no temporally created (which is clearly visible when it happens).<br />
And even if they get it wrong, like for example trying to pass-along an object by value, the compiler will most certainly issue a hint <em>“Looks like, you are returning a reference to a local variable. If you want to return a value use return before the expression”</em>:</p>
<div class="sourceCode" id="cb20"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb20-1"><a href="#cb20-1"></a><span class="op">[](</span><span class="kw">auto</span> a<span class="op">)</span> a;</span>
<span id="cb20-2"><a href="#cb20-2"></a>       <span class="op">~~~^~~~</span> add <span class="cf">return</span></span></code></pre></div>
<p>Of course, there will be cases where the compiler will not be able to “see through”, but how much this would be a problem is impossible to predict. One thing that is works in our favor is the fact, this is a single expression. There are not many sources of local variables that could be returned as a reference. These either have to be the arguments or a temporary, created by a function call chaining in the expression itself.<br />
The first is somewhat questionable in practice, because simple arguments tend to be used to create new values as part of the expression - <code>[](int a) a + 1;</code> - and complex arguments are in general taken by reference - <code>[](const Person&amp; p) p.nameAsRef();</code>. A complex argument taken by value can be used as an optimization technique, but it is rather unlikely to happen on single expression functions. Even if it happens, it will almost certainly be used to create a temporary: <code>[](Rect r) r.width * r.height;</code><br />
The second source for dangling references, function call chaining creating temporaries, is already dangerous and something most programmers are aware of, besides, returning by value only helps to an extent, it’s not magic bullet.<br />
More importantly however, returning a reference to temporary is not <em>necessarily</em> fatal. Chances are, the reference will be used before the end of the expression that created it:</p>
<div class="sourceCode" id="cb21"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb21-1"><a href="#cb21-1"></a>std<span class="op">::</span>partition<span class="op">(</span>begin, end, <span class="op">[](</span>Person p<span class="op">)</span> p<span class="op">.</span>id<span class="op">)</span>; </span>
<span id="cb21-2"><a href="#cb21-2"></a>std<span class="op">::</span>transform<span class="op">(</span>begin, end, dest, <span class="op">[](</span>Person p<span class="op">)</span> p<span class="op">.</span>nameAsRef<span class="op">())</span>; </span>
<span id="cb21-3"><a href="#cb21-3"></a><span class="op">...</span></span>
<span id="cb21-4"><a href="#cb21-4"></a><span class="kw">auto</span> get_person<span class="op">(</span>Person<span class="op">=</span>p<span class="op">{})</span> p;</span>
<span id="cb21-5"><a href="#cb21-5"></a><span class="kw">const</span> <span class="kw">auto</span> person <span class="op">=</span> get_person<span class="op">()</span>; </span></code></pre></div>
<p><em>Returning reference to local is not always a problem.</em></p>
<p>In these, and many other situation returning a reference to local is OK. This is because the expressions are “assignment expressions” which, in the end, will find their way either into a value or into a condition expression, both of which are fine in general. Only “clever” code like assignments to a const reference or a <code>auto&amp;&amp;</code> is really affected, but this is the exception, not the rule and also can be mitigated by <em>not</em> removing the <code>return</code> from the expression, if this is an old code that needs to continue to work.</p>
</section>
<section id="a-minor-detail" data-number="3.1.3">
<h3 data-number="3.1.3"><span class="header-section-number">3.1.3</span> A minor detail<a href="#a-minor-detail" class="self-link"></a></h3>
<p>The proposed minimal expression will not be practical in all case. In particular, it might clash with possible future qualifiers:</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">auto</span> Class<span class="op">::</span>func<span class="op">()</span> async;</span>
<span id="cb22-2"><a href="#cb22-2"></a><span class="op">[](</span><span class="dt">int</span> a<span class="op">)</span> coro;</span></code></pre></div>
<p>In the above hypothetical examples we will write ourself into a corner by allowing the minimal syntax - all future qualifiers will compete with existing expressions. To counter this, it is proposed to terminate any qualifiers by <code>:</code>:</p>
<div class="sourceCode" id="cb23"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb23-1"><a href="#cb23-1"></a><span class="kw">auto</span> Class<span class="op">::</span>member<span class="op">()</span> <span class="kw">const</span><span class="op">:</span> async;</span>
<span id="cb23-2"><a href="#cb23-2"></a><span class="op">[](</span><span class="dt">int</span> a<span class="op">)</span> <span class="kw">mutable</span><span class="op">:</span> coro;</span></code></pre></div>
<p>This way we can introduce new keywords without the danger of clashing with existing expression bodies.<br />
The colon is not needed if <code>return</code> is used:</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">auto</span> Class<span class="op">::</span>member<span class="op">()</span> <span class="kw">const</span> <span class="cf">return</span> async;</span>
<span id="cb24-2"><a href="#cb24-2"></a><span class="op">[](</span><span class="dt">int</span> a<span class="op">)</span> <span class="kw">mutable</span> <span class="cf">return</span> coro;</span></code></pre></div>
<p><em>Colon not needed if we use <code>return</code>.</em></p>
<p>The <code>:</code> is proposed as it has minimal visual and syntactical clutter. It has long history of being a <em>separator</em> (labels, case labels, bitfields, parent classes, parent/member constructor calls) and it also does not have any of the “return” associations that <code>=&gt;</code> has. If we were to use <code>=&gt;</code> here instead, it will be really confusing why sometimes it is not used and how it interacts with <code>return</code>, where <code>:</code> can be presented just as “a separator that is not always needed”.</p>
<blockquote>
<p>Using <code>=</code> was shortly considered, but it is not an option, because it is already used in defaulted, deleted and pure virtual functions.</p>
</blockquote>
</section>
</section>
<section id="examples" data-number="3.2">
<h2 data-number="3.2"><span class="header-section-number">3.2</span> Examples<a href="#examples" class="self-link"></a></h2>
<div class="columns">
<div class="column" style="width:50%;">
<p><strong>Current implementation</strong></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">class</span> <span class="ex">QPointF</span></span>
<span id="cb25-2"><a href="#cb25-2"></a><span class="op">{</span></span>
<span id="cb25-3"><a href="#cb25-3"></a>  <span class="op">...</span></span>
<span id="cb25-4"><a href="#cb25-4"></a>  real<span class="op">&amp;</span> rx<span class="op">()</span> <span class="op">{</span> <span class="cf">return</span> xp; <span class="op">}</span></span>
<span id="cb25-5"><a href="#cb25-5"></a>  real<span class="op">&amp;</span> ry<span class="op">()</span> <span class="op">{</span> <span class="cf">return</span> yp; <span class="op">}</span></span>
<span id="cb25-6"><a href="#cb25-6"></a>   real x<span class="op">()</span> <span class="kw">const</span> <span class="op">{</span> <span class="cf">return</span> xp; <span class="op">}</span></span>
<span id="cb25-7"><a href="#cb25-7"></a>   real y<span class="op">()</span> <span class="kw">const</span> <span class="op">{</span> <span class="cf">return</span> yp; <span class="op">}</span></span>
<span id="cb25-8"><a href="#cb25-8"></a>   </span>
<span id="cb25-9"><a href="#cb25-9"></a>  <span class="kw">friend</span> <span class="kw">auto</span> <span class="kw">operator</span><span class="op">+(</span><span class="kw">const</span> <span class="ex">QPointF</span> <span class="op">&amp;</span>p1, <span class="kw">const</span> <span class="ex">QPointF</span> <span class="op">&amp;</span>p2<span class="op">)</span> <span class="op">{</span></span>
<span id="cb25-10"><a href="#cb25-10"></a>    <span class="cf">return</span> <span class="ex">QPointF</span><span class="op">(</span>p1<span class="op">.</span>xp<span class="op">+</span>p2<span class="op">.</span>xp, p1<span class="op">.</span>yp<span class="op">+</span>p2<span class="op">.</span>yp<span class="op">)</span>;</span>
<span id="cb25-11"><a href="#cb25-11"></a>  <span class="op">}</span></span>
<span id="cb25-12"><a href="#cb25-12"></a></span>
<span id="cb25-13"><a href="#cb25-13"></a><span class="kw">private</span><span class="op">:</span></span>
<span id="cb25-14"><a href="#cb25-14"></a>  real xp;</span>
<span id="cb25-15"><a href="#cb25-15"></a>  real yp;</span>
<span id="cb25-16"><a href="#cb25-16"></a><span class="op">}</span>;</span></code></pre></div>
</div><div class="column" style="width:50%;">
<p><strong>Same return, a bit less typing, <em>correct <code>noexcept</code></em></strong></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">class</span> <span class="ex">QPointF</span></span>
<span id="cb26-2"><a href="#cb26-2"></a><span class="op">{</span></span>
<span id="cb26-3"><a href="#cb26-3"></a>  <span class="op">...</span></span>
<span id="cb26-4"><a href="#cb26-4"></a>  <span class="kw">auto</span> rx<span class="op">()</span> xp; </span>
<span id="cb26-5"><a href="#cb26-5"></a>  <span class="kw">auto</span> ry<span class="op">()</span> yp;</span>
<span id="cb26-6"><a href="#cb26-6"></a>  <span class="kw">auto</span> x<span class="op">()</span> <span class="kw">const</span> <span class="cf">return</span> xp;</span>
<span id="cb26-7"><a href="#cb26-7"></a>  <span class="kw">auto</span> y<span class="op">()</span> <span class="kw">const</span> <span class="cf">return</span> yp;</span>
<span id="cb26-8"><a href="#cb26-8"></a></span>
<span id="cb26-9"><a href="#cb26-9"></a>  <span class="kw">friend</span> <span class="kw">auto</span> <span class="kw">operator</span><span class="op">+(</span><span class="kw">const</span> <span class="ex">QPointF</span> <span class="op">&amp;</span>p1, <span class="kw">const</span> <span class="ex">QPointF</span> <span class="op">&amp;</span>p2<span class="op">)</span></span>
<span id="cb26-10"><a href="#cb26-10"></a>    <span class="ex">QPointF</span><span class="op">(</span>p1<span class="op">.</span>xp<span class="op">+</span>p2<span class="op">.</span>xp, p1<span class="op">.</span>yp<span class="op">+</span>p2<span class="op">.</span>yp<span class="op">)</span>;</span>
<span id="cb26-11"><a href="#cb26-11"></a></span>
<span id="cb26-12"><a href="#cb26-12"></a><span class="kw">private</span><span class="op">:</span></span>
<span id="cb26-13"><a href="#cb26-13"></a>  real xp;</span>
<span id="cb26-14"><a href="#cb26-14"></a>  real yp;</span>
<span id="cb26-15"><a href="#cb26-15"></a><span class="op">}</span>;</span></code></pre></div>
</div>
</div>
<div class="columns">
<div class="column" style="width:50%;">
<p><strong>Current implementation (expert)</strong></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">template</span><span class="op">&lt;</span> <span class="kw">class</span> C <span class="op">&gt;</span></span>
<span id="cb27-2"><a href="#cb27-2"></a><span class="kw">constexpr</span> </span>
<span id="cb27-3"><a href="#cb27-3"></a><span class="kw">auto</span> cbegin<span class="op">(</span> <span class="kw">const</span> C<span class="op">&amp;</span> c <span class="op">)</span> <span class="kw">noexcept</span><span class="op">(</span><span class="kw">noexcept</span><span class="op">(</span>std<span class="op">::</span>begin<span class="op">(</span>c<span class="op">)))</span></span>
<span id="cb27-4"><a href="#cb27-4"></a>    <span class="op">-&gt;</span> <span class="kw">decltype</span><span class="op">(</span>std<span class="op">::</span>begin<span class="op">(</span>c<span class="op">))</span> <span class="op">{</span> <span class="cf">return</span> std<span class="op">::</span>begin<span class="op">(</span>c<span class="op">)</span>; <span class="op">}</span> </span></code></pre></div>
</div><div class="column" style="width:50%;">
<p><strong>Correct by default (noob friendly)</strong></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">template</span><span class="op">&lt;</span> <span class="kw">class</span> C <span class="op">&gt;</span></span>
<span id="cb28-2"><a href="#cb28-2"></a><span class="kw">constexpr</span> </span>
<span id="cb28-3"><a href="#cb28-3"></a><span class="kw">auto</span> cbegin<span class="op">(</span> <span class="kw">const</span> C<span class="op">&amp;</span> c <span class="op">)</span> std<span class="op">::</span>begin<span class="op">(</span>c<span class="op">)</span>; </span></code></pre></div>
</div>
</div>
</section>
<section id="the-bigger-picture" data-number="3.3">
<h2 data-number="3.3"><span class="header-section-number">3.3</span> The Bigger picture<a href="#the-bigger-picture" class="self-link"></a></h2>
<p>The importance of minimal syntax comes into play when we view it as both alternative to the “overloading set” feature, proposed <em>multiple</em> times recently (<a href="#fn8" class="footnote-ref" id="fnref8" role="doc-noteref"><sup>8</sup></a>,<a href="#fn9" class="footnote-ref" id="fnref9" role="doc-noteref"><sup>9</sup></a>,<a href="#fn10" class="footnote-ref" id="fnref10" role="doc-noteref"><sup>10</sup></a>), as well as a potential stepping stone to the so called “hyper-abbreviated” lambdas<a href="#fn11" class="footnote-ref" id="fnref11" role="doc-noteref"><sup>11</sup></a>:</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="kw">auto</span> func<span class="op">(</span><span class="kw">const</span> std<span class="op">::</span>string<span class="op">&amp;)</span>;</span>
<span id="cb29-2"><a href="#cb29-2"></a><span class="kw">auto</span> func<span class="op">(</span><span class="kw">const</span> <span class="ex">QString</span><span class="op">&amp;)</span>;</span>
<span id="cb29-3"><a href="#cb29-3"></a><span class="kw">auto</span> func<span class="op">(</span><span class="dt">int</span><span class="op">)</span> <span class="kw">noexcept</span>;</span>
<span id="cb29-4"><a href="#cb29-4"></a><span class="kw">inline</span> <span class="kw">constexpr</span> <span class="kw">auto</span> func_o <span class="op">=</span> <span class="op">[](</span><span class="kw">const</span> <span class="kw">auto</span><span class="op">&amp;</span> val<span class="op">)</span> func<span class="op">(</span>val<span class="op">)</span>; </span>
<span id="cb29-5"><a href="#cb29-5"></a></span>
<span id="cb29-6"><a href="#cb29-6"></a>std<span class="op">::</span>transform<span class="op">(</span>sv<span class="op">.</span>begin<span class="op">()</span>, sv<span class="op">.</span>end<span class="op">()</span>, sv<span class="op">.</span>begin<span class="op">()</span>, func_o<span class="op">)</span>;</span>
<span id="cb29-7"><a href="#cb29-7"></a>std<span class="op">::</span>transform<span class="op">(</span>qv<span class="op">.</span>begin<span class="op">()</span>, qv<span class="op">.</span>end<span class="op">()</span>, qv<span class="op">.</span>begin<span class="op">()</span>, func_o<span class="op">)</span>;</span>
<span id="cb29-8"><a href="#cb29-8"></a>std<span class="op">::</span>transform<span class="op">(</span>iv<span class="op">.</span>begin<span class="op">()</span>, iv<span class="op">.</span>end<span class="op">()</span>, iv<span class="op">.</span>begin<span class="op">()</span>, func_o<span class="op">)</span>;</span></code></pre></div>
<p><em>Viable “overloading set” alternative.</em></p>
<p>Another example, modified from <strong>p0119</strong>, with the <strong>P2425R0</strong> <strong>Abbreviated Parameters</strong> proposal.</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="co">// Modified from p0119, with </span></span>
<span id="cb30-2"><a href="#cb30-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="cb30-3"><a href="#cb30-3"></a>T twice<span class="op">(</span>T x<span class="op">)</span></span>
<span id="cb30-4"><a href="#cb30-4"></a><span class="op">{</span></span>
<span id="cb30-5"><a href="#cb30-5"></a>  <span class="cf">return</span> x <span class="op">*</span> <span class="dv">2</span>;</span>
<span id="cb30-6"><a href="#cb30-6"></a><span class="op">}</span></span>
<span id="cb30-7"><a href="#cb30-7"></a></span>
<span id="cb30-8"><a href="#cb30-8"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">typename</span> It<span class="op">&gt;</span></span>
<span id="cb30-9"><a href="#cb30-9"></a><span class="dt">void</span> f<span class="op">(</span>It first, It second<span class="op">)</span></span>
<span id="cb30-10"><a href="#cb30-10"></a><span class="op">{</span></span>
<span id="cb30-11"><a href="#cb30-11"></a>  std<span class="op">::</span>transform<span class="op">(</span>first, second, first, <span class="op">[]((</span>a<span class="op">))</span> twice<span class="op">(</span>a<span class="op">))</span>; <span class="co">//&lt; Close enough to &quot;lifting&quot;?</span></span>
<span id="cb30-12"><a href="#cb30-12"></a><span class="op">}</span></span></code></pre></div>
<p><em>Inline “overloading set” creation.</em></p>
<p>Going further into some theoretical “hyper-abbreviated” expression is natural:</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">template</span><span class="op">&lt;</span><span class="kw">typename</span> It<span class="op">&gt;</span></span>
<span id="cb31-2"><a href="#cb31-2"></a><span class="dt">void</span> f<span class="op">(</span>It first, It second<span class="op">)</span></span>
<span id="cb31-3"><a href="#cb31-3"></a><span class="op">{</span></span>
<span id="cb31-4"><a href="#cb31-4"></a>  std<span class="op">::</span>transform<span class="op">(</span>first, second, first, <span class="op">[]</span> twice<span class="op">(</span><span class="dv">1</span><span class="op">:))</span>; <span class="co">//&lt; `1:` a &quot;placeholder literal&quot;? </span></span>
<span id="cb31-5"><a href="#cb31-5"></a><span class="op">}</span></span></code></pre></div>
<p>Here is the place to note, in the minimal form, the space after either <code>[]</code> or after <code>:</code> <strong>is required</strong>:</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="co">// auto l1 = []something;  //&lt; wrong, space needed after `[]`</span></span>
<span id="cb32-2"><a href="#cb32-2"></a><span class="co">// auto l2 = [=]mutable:something.doIt(); //&lt; wrong, space needed after `:`</span></span></code></pre></div>
<p>The reason for this to not consume syntax that might be used for other purposes. The <code>[]</code> as a prefix was already proposed for both overloading set lifting <em>and</em>, for the completely unrelated, language-based support for <code>std::get&lt;index&gt;(structure)</code>, the <code>[index]structure</code> syntax.<br />
Expecting some use of <code>:</code> as a prefix is also reasonable. Currently it is only used for module fragments. Not only that, but if the space is not required we will end up with needlessly odd code like this <code>&lt;modifier&gt;:::value_in_global_sclope.</code></p>
<p>Last but not least, minimal syntax is also (extremely) important for lazy arguments usage. From <strong>p2218</strong><a href="#fn12" class="footnote-ref" id="fnref12" role="doc-noteref"><sup>12</sup></a>:</p>
<div class="sourceCode" id="cb33"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb33-1"><a href="#cb33-1"></a>optional<span class="op">&lt;</span>vector<span class="op">&lt;</span>string<span class="op">&gt;&gt;</span> opt <span class="op">=</span> <span class="op">~~~</span>;</span>
<span id="cb33-2"><a href="#cb33-2"></a><span class="op">...</span></span>
<span id="cb33-3"><a href="#cb33-3"></a><span class="co">// From</span></span>
<span id="cb33-4"><a href="#cb33-4"></a><span class="kw">auto</span> v3 <span class="op">=</span> opt<span class="op">.</span>value_or_else<span class="op">([]</span> <span class="op">{</span> <span class="cf">return</span> vector<span class="op">{</span><span class="st">&quot;Hello&quot;</span><span class="bu">s</span> , <span class="st">&quot;World&quot;</span><span class="bu">s</span><span class="op">}</span>; <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="co">// To (this proposal)</span></span>
<span id="cb33-7"><a href="#cb33-7"></a><span class="kw">auto</span> v3 <span class="op">=</span> opt<span class="op">.</span>value_or_else<span class="op">([]</span> vector<span class="op">{</span><span class="st">&quot;Hello&quot;</span><span class="bu">s</span> , <span class="st">&quot;World&quot;</span><span class="bu">s</span><span class="op">})</span>;</span></code></pre></div>
<p>As you can see, minimal syntax get us 99% of “real” lazy arguments.</p>
<blockquote>
<p>Here again it is worth repeating, it is not <em>just</em> about the syntax. The exception specification propagation is equally if not more important. A lazy argument <em>must</em> have the same requirements as the value it constructs. In the above example, surely both <code>vector</code> and <code>string</code> throw, but we can image something like <code>[] Brush(Color::red)</code>, that might as well have <code>noexcept</code> construction.</p>
</blockquote>
</section>
<section id="alternatives" data-number="3.4">
<h2 data-number="3.4"><span class="header-section-number">3.4</span> Alternatives<a href="#alternatives" class="self-link"></a></h2>
<p><strong>Variant One</strong>, where the reference semantics are the default, could have two alternatives.</p>
<section id="alternative-1" data-number="3.4.1">
<h3 data-number="3.4.1"><span class="header-section-number">3.4.1</span> Alternative 1<a href="#alternative-1" class="self-link"></a></h3>
<p>Use <code>=&gt;</code> instead of <code>return</code> for the return-by-value option.</p>
<div class="columns">
<div class="column" style="width:50%;">
<p><strong>Main proposal</strong></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">class</span> <span class="ex">QPointF</span></span>
<span id="cb34-2"><a href="#cb34-2"></a><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 class="kw">auto</span> rx<span class="op">()</span> xp; </span>
<span id="cb34-5"><a href="#cb34-5"></a>  <span class="kw">auto</span> ry<span class="op">()</span> yp;</span>
<span id="cb34-6"><a href="#cb34-6"></a>  <span class="kw">auto</span> x<span class="op">()</span> <span class="kw">const</span> <span class="cf">return</span> xp; <span class="co">//&lt; by value</span></span>
<span id="cb34-7"><a href="#cb34-7"></a>  <span class="kw">auto</span> y<span class="op">()</span> <span class="kw">const</span> <span class="cf">return</span> yp; <span class="co">//</span></span>
<span id="cb34-8"><a href="#cb34-8"></a></span>
<span id="cb34-9"><a href="#cb34-9"></a>  <span class="op">...</span></span>
<span id="cb34-10"><a href="#cb34-10"></a><span class="op">}</span>;</span></code></pre></div>
</div><div class="column" style="width:50%;">
<p><strong>Alternative 1</strong></p>
<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> <span class="ex">QPointF</span></span>
<span id="cb35-2"><a href="#cb35-2"></a><span class="op">{</span></span>
<span id="cb35-3"><a href="#cb35-3"></a>  <span class="op">...</span></span>
<span id="cb35-4"><a href="#cb35-4"></a>  <span class="kw">auto</span> rx<span class="op">()</span> xp; </span>
<span id="cb35-5"><a href="#cb35-5"></a>  <span class="kw">auto</span> ry<span class="op">()</span> yp;</span>
<span id="cb35-6"><a href="#cb35-6"></a>  <span class="kw">auto</span> x<span class="op">()</span> <span class="kw">const</span> <span class="op">=&gt;</span> xp; <span class="co">//&lt; by value</span></span>
<span id="cb35-7"><a href="#cb35-7"></a>  <span class="kw">auto</span> y<span class="op">()</span> <span class="kw">const</span> <span class="op">=&gt;</span> yp; <span class="co">//</span></span>
<span id="cb35-8"><a href="#cb35-8"></a></span>
<span id="cb35-9"><a href="#cb35-9"></a>  <span class="op">...</span></span>
<span id="cb35-10"><a href="#cb35-10"></a><span class="op">}</span>;</span></code></pre></div>
</div>
</div>
<p>We get few characters back, but lose the natural transition from regular functions. It is also questionable if people will be able to remember when to use (or not) <code>=&gt;</code>, where using <code>return</code> does have the whole “going back” to a normal function association. This is the reason why this is not the first choice.</p>
</section>
<section id="alternative-2" data-number="3.4.2">
<h3 data-number="3.4.2"><span class="header-section-number">3.4.2</span> Alternative 2<a href="#alternative-2" class="self-link"></a></h3>
<p>The other alternative is to have just one option - return by reference - and use constructs like <code>auto(x)</code><a href="#fn13" class="footnote-ref" id="fnref13" role="doc-noteref"><sup>13</sup></a> to get a value out of the expression.</p>
<div class="columns">
<div class="column" style="width:50%;">
<p><strong>Main proposal</strong></p>
<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> <span class="ex">QPointF</span></span>
<span id="cb36-2"><a href="#cb36-2"></a><span class="op">{</span></span>
<span id="cb36-3"><a href="#cb36-3"></a>  <span class="op">...</span></span>
<span id="cb36-4"><a href="#cb36-4"></a>  <span class="kw">auto</span> rx<span class="op">()</span> xp; </span>
<span id="cb36-5"><a href="#cb36-5"></a>  <span class="kw">auto</span> ry<span class="op">()</span> yp;</span>
<span id="cb36-6"><a href="#cb36-6"></a>  <span class="kw">auto</span> x<span class="op">()</span> <span class="kw">const</span> <span class="cf">return</span> xp; <span class="co">//&lt; by value</span></span>
<span id="cb36-7"><a href="#cb36-7"></a>  <span class="kw">auto</span> y<span class="op">()</span> <span class="kw">const</span> <span class="cf">return</span> yp; <span class="co">//</span></span>
<span id="cb36-8"><a href="#cb36-8"></a></span>
<span id="cb36-9"><a href="#cb36-9"></a>  <span class="op">...</span></span>
<span id="cb36-10"><a href="#cb36-10"></a><span class="op">}</span>;</span></code></pre></div>
</div><div class="column" style="width:50%;">
<p><strong>Alternative 1</strong></p>
<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">class</span> <span class="ex">QPointF</span></span>
<span id="cb37-2"><a href="#cb37-2"></a><span class="op">{</span></span>
<span id="cb37-3"><a href="#cb37-3"></a>  <span class="op">...</span></span>
<span id="cb37-4"><a href="#cb37-4"></a>  <span class="kw">auto</span> rx<span class="op">()</span> xp; </span>
<span id="cb37-5"><a href="#cb37-5"></a>  <span class="kw">auto</span> ry<span class="op">()</span> yp;</span>
<span id="cb37-6"><a href="#cb37-6"></a>  <span class="kw">auto</span> x<span class="op">()</span> <span class="kw">const</span> <span class="kw">auto</span><span class="op">(</span>xp<span class="op">)</span>; <span class="co">//&lt; by value</span></span>
<span id="cb37-7"><a href="#cb37-7"></a>  <span class="kw">auto</span> y<span class="op">()</span> <span class="kw">const</span> <span class="kw">auto</span><span class="op">(</span>yp<span class="op">)</span>; <span class="co">//</span></span>
<span id="cb37-8"><a href="#cb37-8"></a></span>
<span id="cb37-9"><a href="#cb37-9"></a>  <span class="op">...</span></span>
<span id="cb37-10"><a href="#cb37-10"></a><span class="op">}</span>;</span></code></pre></div>
</div>
</div>
<p>The benefit of this option that is “simple”, as there is only one syntax and getting a value is somewhat “natural”, in the sense we don’t need “special syntax”, but reuse constructs already in the language instead (assuming <code>auto(x)</code> gets approved).<br />
There are drawbacks however. The main issue is, this is ultimately a crutch, a “patch up” for the expression that does not behave as desired. It is not exactly natural to get from normal functions to this. In a way we would have two extremes - by value (or verbose) normal functions and reference only expressions + “a patch” to get back the old behavior. Using <code>return</code> does create a more seamless transition b/w the two.</p>
</section>
</section>
<section id="variant-two-alternative" data-number="3.5">
<h2 data-number="3.5"><span class="header-section-number">3.5</span> Variant Two (Alternative)<a href="#variant-two-alternative" class="self-link"></a></h2>
<p>This variant flips the defaults, giving precedence of “by value” to be used at minimum syntax:</p>
<div class="sourceCode" id="cb38"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb38-1"><a href="#cb38-1"></a><span class="dt">int</span> i;</span>
<span id="cb38-2"><a href="#cb38-2"></a><span class="kw">auto</span> l <span class="op">=</span> <span class="op">[](</span><span class="dt">int</span><span class="op">*</span> p<span class="op">)</span> <span class="op">*</span>p; </span>
<span id="cb38-3"><a href="#cb38-3"></a></span>
<span id="cb38-4"><a href="#cb38-4"></a><span class="co">// decltype(l(&amp;i)) is int</span></span>
<span id="cb38-5"><a href="#cb38-5"></a></span>
<span id="cb38-6"><a href="#cb38-6"></a><span class="co">// equivalent of </span></span>
<span id="cb38-7"><a href="#cb38-7"></a><span class="kw">auto</span> l <span class="op">=</span> <span class="op">[](</span><span class="kw">auto</span><span class="op">*</span> p<span class="op">)</span> <span class="kw">noexcept</span><span class="op">(</span><span class="kw">noexcept</span><span class="op">(</span>std<span class="op">::</span>decay_t<span class="op">&lt;</span><span class="kw">decltype</span><span class="op">(*</span>p<span class="op">)&gt;(*</span>p<span class="op">)))</span> </span>
<span id="cb38-8"><a href="#cb38-8"></a><span class="op">-&gt;</span> <span class="kw">decltype</span><span class="op">(</span>std<span class="op">::</span>decay_t<span class="op">&lt;</span><span class="kw">decltype</span><span class="op">(*</span>p<span class="op">)&gt;(*</span>p<span class="op">))</span> <span class="op">{</span> <span class="cf">return</span> <span class="op">*</span>p; <span class="op">}</span>; </span></code></pre></div>
<p><em>Minimal syntax returns a value.</em></p>
<p>If the user wants reference semantics, the expression must be enclosed with parentheses:</p>
<div class="sourceCode" id="cb39"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb39-1"><a href="#cb39-1"></a><span class="dt">int</span> i;</span>
<span id="cb39-2"><a href="#cb39-2"></a><span class="kw">auto</span> l <span class="op">=</span> <span class="op">[](</span><span class="dt">int</span><span class="op">*</span> p<span class="op">)</span> <span class="op">(*</span>p<span class="op">)</span>; </span>
<span id="cb39-3"><a href="#cb39-3"></a></span>
<span id="cb39-4"><a href="#cb39-4"></a><span class="co">// decltype(l(&amp;i)) is int&amp;</span></span>
<span id="cb39-5"><a href="#cb39-5"></a></span>
<span id="cb39-6"><a href="#cb39-6"></a><span class="co">// equivalent of </span></span>
<span id="cb39-7"><a href="#cb39-7"></a><span class="kw">auto</span> l <span class="op">=</span> <span class="op">[](</span><span class="kw">auto</span><span class="op">*</span> p<span class="op">)</span> <span class="kw">noexcept</span><span class="op">(</span><span class="kw">noexcept</span><span class="op">(*</span>p<span class="op">))</span> </span>
<span id="cb39-8"><a href="#cb39-8"></a><span class="op">-&gt;</span> <span class="kw">decltype</span><span class="op">((*</span>p<span class="op">))</span> <span class="op">{</span> <span class="cf">return</span> <span class="op">*</span>p; <span class="op">}</span>; </span></code></pre></div>
<p><em>Using <code>()</code> enables return by reference.</em></p>
<section id="motivation-1" data-number="3.5.1">
<h3 data-number="3.5.1"><span class="header-section-number">3.5.1</span> Motivation<a href="#motivation-1" class="self-link"></a></h3>
<p>Using parentheses to get a reference is already established practice in <code>return</code> and <code>decltype</code> expressions, used with an identifier or member access:</p>
<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">auto</span> l <span class="op">=</span> <span class="op">[](</span><span class="dt">int</span> i<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 class="cf">return</span> <span class="op">(</span>i<span class="op">)</span>; <span class="op">}</span>;  <span class="co">//&lt; already returns a reference</span></span>
<span id="cb40-2"><a href="#cb40-2"></a></span>
<span id="cb40-3"><a href="#cb40-3"></a><span class="kw">struct</span> Point <span class="op">{</span> <span class="dt">int</span> x; <span class="dt">int</span> y; <span class="op">}</span>;</span>
<span id="cb40-4"><a href="#cb40-4"></a><span class="kw">auto</span> l2 <span class="op">=</span> <span class="op">[](</span><span class="kw">const</span> Point<span class="op">&amp;</span> p<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 class="cf">return</span> <span class="op">(</span>p<span class="op">.</span>x<span class="op">)</span>; <span class="op">}</span>;  <span class="co">//&lt; already returns a reference</span></span>
<span id="cb40-5"><a href="#cb40-5"></a></span>
<span id="cb40-6"><a href="#cb40-6"></a><span class="dt">int</span> i;</span>
<span id="cb40-7"><a href="#cb40-7"></a><span class="kw">decltype</span><span class="op">((</span>i<span class="op">))</span> p <span class="op">=</span> i; <span class="co">//&lt; p is a reference</span></span></code></pre></div>
<p><em>Established use of <code>()</code> to get reference for an expression.</em></p>
<p>Proposed is to have parentheses around the expression behave the same for all expressions:</p>
<div class="sourceCode" id="cb41"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb41-1"><a href="#cb41-1"></a><span class="op">[](</span>Person p<span class="op">)</span> p<span class="op">.</span>id;            <span class="co">//&lt; returns int</span></span>
<span id="cb41-2"><a href="#cb41-2"></a><span class="op">[](</span>Person p<span class="op">)</span> <span class="op">(</span>p<span class="op">.</span>id<span class="op">)</span>;          <span class="co">//&lt; returns int&amp; (as currently)</span></span>
<span id="cb41-3"><a href="#cb41-3"></a></span>
<span id="cb41-4"><a href="#cb41-4"></a><span class="op">[](</span>Person p<span class="op">)</span> p<span class="op">.</span>nameAsRef<span class="op">()</span>;   <span class="co">//&lt; returns string </span></span>
<span id="cb41-5"><a href="#cb41-5"></a><span class="op">[](</span>Person p<span class="op">)</span> <span class="op">(</span>p<span class="op">.</span>nameAsRef<span class="op">())</span>; <span class="co">//&lt; returns string&amp; (proposed)</span></span>
<span id="cb41-6"><a href="#cb41-6"></a></span>
<span id="cb41-7"><a href="#cb41-7"></a><span class="co">// returns a value (or void)</span></span>
<span id="cb41-8"><a href="#cb41-8"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> F, <span class="kw">class</span><span class="op">...</span> Args<span class="op">&gt;</span></span>
<span id="cb41-9"><a href="#cb41-9"></a><span class="kw">auto</span> passthrough<span class="op">(</span>T<span class="op">&amp;&amp;</span> f, Args<span class="op">&amp;&amp;...</span> args<span class="op">)</span> std<span class="op">::</span>invoke<span class="op">(</span>std<span class="op">::</span>forward<span class="op">&lt;</span>F<span class="op">&gt;(</span>f<span class="op">)</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>Args<span class="op">&gt;(</span>args<span class="op">)...)</span>; </span>
<span id="cb41-10"><a href="#cb41-10"></a></span>
<span id="cb41-11"><a href="#cb41-11"></a><span class="co">// returns whatever std::invoke returns</span></span>
<span id="cb41-12"><a href="#cb41-12"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> F, <span class="kw">class</span><span class="op">...</span> Args<span class="op">&gt;</span></span>
<span id="cb41-13"><a href="#cb41-13"></a><span class="kw">auto</span> passthrough<span class="op">(</span>T<span class="op">&amp;&amp;</span> f, Args<span class="op">&amp;&amp;...</span> args<span class="op">)</span> <span class="op">(</span>std<span class="op">::</span>invoke<span class="op">(</span>std<span class="op">::</span>forward<span class="op">&lt;</span>F<span class="op">&gt;(</span>f<span class="op">)</span>, std<span class="op">::</span>forward<span class="op">&lt;</span>Args<span class="op">&gt;(</span>args<span class="op">)...))</span>; </span></code></pre></div>
<p>Needless to say, in all cases the correct <code>noexcept</code> and concept-friendliness are added where appropriate.</p>
<p>Similar to <strong>Variant One</strong>, the minimal syntax will require <code>:</code> as separator in some cases, but not when parenths are used:</p>
<div class="sourceCode" id="cb42"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb42-1"><a href="#cb42-1"></a><span class="op">[</span>object<span class="op">]</span><span class="kw">mutable</span><span class="op">:</span> object<span class="op">.</span>func<span class="op">()</span>;  <span class="co">//&lt; by value, minimal syntax, separator after specifier needed</span></span>
<span id="cb42-2"><a href="#cb42-2"></a><span class="op">[</span>object<span class="op">]</span><span class="kw">mutable</span> <span class="op">(</span>object<span class="op">.</span>func<span class="op">())</span>; <span class="co">//&lt; by reference, separator not needed</span></span></code></pre></div>
</section>
<section id="example" data-number="3.5.2">
<h3 data-number="3.5.2"><span class="header-section-number">3.5.2</span> Example<a href="#example" class="self-link"></a></h3>
<div class="columns">
<div class="column" style="width:50%;">
<p><strong>Current implementation</strong></p>
<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">class</span> <span class="ex">QPointF</span></span>
<span id="cb43-2"><a href="#cb43-2"></a><span class="op">{</span></span>
<span id="cb43-3"><a href="#cb43-3"></a>  <span class="op">...</span></span>
<span id="cb43-4"><a href="#cb43-4"></a>  real<span class="op">&amp;</span> rx<span class="op">()</span> <span class="op">{</span> <span class="cf">return</span> xp; <span class="op">}</span></span>
<span id="cb43-5"><a href="#cb43-5"></a>  real<span class="op">&amp;</span> ry<span class="op">()</span> <span class="op">{</span> <span class="cf">return</span> yp; <span class="op">}</span></span>
<span id="cb43-6"><a href="#cb43-6"></a>   real x<span class="op">()</span> <span class="kw">const</span> <span class="op">{</span> <span class="cf">return</span> xp; <span class="op">}</span></span>
<span id="cb43-7"><a href="#cb43-7"></a>   real y<span class="op">()</span> <span class="kw">const</span> <span class="op">{</span> <span class="cf">return</span> yp; <span class="op">}</span></span>
<span id="cb43-8"><a href="#cb43-8"></a>   </span>
<span id="cb43-9"><a href="#cb43-9"></a>  <span class="kw">friend</span> <span class="kw">auto</span> <span class="kw">operator</span><span class="op">+(</span><span class="kw">const</span> <span class="ex">QPointF</span> <span class="op">&amp;</span>p1, <span class="kw">const</span> <span class="ex">QPointF</span> <span class="op">&amp;</span>p2<span class="op">)</span> <span class="op">{</span></span>
<span id="cb43-10"><a href="#cb43-10"></a>    <span class="cf">return</span> <span class="ex">QPointF</span><span class="op">(</span>p1<span class="op">.</span>xp<span class="op">+</span>p2<span class="op">.</span>xp, p1<span class="op">.</span>yp<span class="op">+</span>p2<span class="op">.</span>yp<span class="op">)</span>;</span>
<span id="cb43-11"><a href="#cb43-11"></a>  <span class="op">}</span></span>
<span id="cb43-12"><a href="#cb43-12"></a></span>
<span id="cb43-13"><a href="#cb43-13"></a><span class="kw">private</span><span class="op">:</span></span>
<span id="cb43-14"><a href="#cb43-14"></a>  real xp;</span>
<span id="cb43-15"><a href="#cb43-15"></a>  real yp;</span>
<span id="cb43-16"><a href="#cb43-16"></a><span class="op">}</span>;</span></code></pre></div>
</div><div class="column" style="width:50%;">
<p><strong>Same return, a bit less typing, <em>free <code>noexcept</code></em></strong></p>
<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">class</span> <span class="ex">QPointF</span></span>
<span id="cb44-2"><a href="#cb44-2"></a><span class="op">{</span></span>
<span id="cb44-3"><a href="#cb44-3"></a>  <span class="op">...</span></span>
<span id="cb44-4"><a href="#cb44-4"></a>  <span class="kw">auto</span> rx<span class="op">()</span> <span class="op">(</span>xp<span class="op">)</span>; </span>
<span id="cb44-5"><a href="#cb44-5"></a>  <span class="kw">auto</span> ry<span class="op">()</span> <span class="op">(</span>yp<span class="op">)</span>;</span>
<span id="cb44-6"><a href="#cb44-6"></a>  <span class="kw">auto</span> x<span class="op">()</span> <span class="kw">const</span><span class="op">:</span> xp;</span>
<span id="cb44-7"><a href="#cb44-7"></a>  <span class="kw">auto</span> y<span class="op">()</span> <span class="kw">const</span><span class="op">:</span> yp;</span>
<span id="cb44-8"><a href="#cb44-8"></a></span>
<span id="cb44-9"><a href="#cb44-9"></a>  <span class="kw">friend</span> <span class="kw">auto</span> <span class="kw">operator</span><span class="op">+(</span><span class="kw">const</span> <span class="ex">QPointF</span> <span class="op">&amp;</span>p1, <span class="kw">const</span> <span class="ex">QPointF</span> <span class="op">&amp;</span>p2<span class="op">)</span></span>
<span id="cb44-10"><a href="#cb44-10"></a>    <span class="ex">QPointF</span><span class="op">(</span>p1<span class="op">.</span>xp<span class="op">+</span>p2<span class="op">.</span>xp, p1<span class="op">.</span>yp<span class="op">+</span>p2<span class="op">.</span>yp<span class="op">)</span>;</span>
<span id="cb44-11"><a href="#cb44-11"></a></span>
<span id="cb44-12"><a href="#cb44-12"></a><span class="kw">private</span><span class="op">:</span></span>
<span id="cb44-13"><a href="#cb44-13"></a>  real xp;</span>
<span id="cb44-14"><a href="#cb44-14"></a>  real yp;</span>
<span id="cb44-15"><a href="#cb44-15"></a><span class="op">}</span>;</span></code></pre></div>
</div>
</div>
</section>
<section id="why-is-variant-two-not-the-main-proposal" data-number="3.5.3">
<h3 data-number="3.5.3"><span class="header-section-number">3.5.3</span> Why is <strong>Variant Two</strong> not the main proposal?<a href="#why-is-variant-two-not-the-main-proposal" class="self-link"></a></h3>
<p>There are few reasons for that. Reason one is the speculation, reference being the default will be right, or it will simply not matter - most functions will be used in assignment to value or comparison and/or they will create a temporary either way. That aside, parentheses might seem an obscure way of expressing reference semantics, after all not many people are aware of their usage in <code>return</code> and <code>decltype</code>. And for people that <em>are</em> aware of these uses, it might seem inconsistent to change the rules in such a way, have special handling of parentheses in expressions of this type (and this type alone).</p>
</section>
</section>
<section id="conclusion" data-number="3.6">
<h2 data-number="3.6"><span class="header-section-number">3.6</span> Conclusion<a href="#conclusion" class="self-link"></a></h2>
<p>Presented here were multiple paths to handle <em>one</em> of the issues that prevented the original <strong>Abbreviated Lambdas</strong> proposal being accepted. This proposal sees the significant value of having expressions functions bodies not so much for “abbreviating” code, but making it <em>correct by default</em>.<br />
The alternatives we have to today are impractical in day-to-day code to the extend, they are not even recommended by experts<a href="#fn14" class="footnote-ref" id="fnref14" role="doc-noteref"><sup>14</sup></a>, and/or are insufferable in library code.</p>
<p><strong>Arguably, there are not many features that will improve <em>both</em> the code <em>and</em> the experience for <em>both</em> the library writers <em>and</em> regular developers.</strong></p>
<hr />
</section>
</section>
<section class="footnotes" role="doc-endnotes">
<hr />
<ol>
<li id="fn1" role="doc-endnote"><p>Abbreviated Lambdas: <a href="http://www.open-std.or/jtc1/sc22/wg21/docs/papers/2017/p0573r2.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0573r2.html</a><a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn2" role="doc-endnote"><p>Abbreviated Lambdas: <a href="http://www.open-std.or/jtc1/sc22/wg21/docs/papers/2017/p0573r2.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0573r2.html</a><a href="#fnref2" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn3" role="doc-endnote"><p>Abbreviated Lambdas: <a href="http://www.open-std.or/jtc1/sc22/wg21/docs/papers/2017/p0573r2.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0573r2.html</a><a href="#fnref3" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn4" role="doc-endnote"><p>Zero-overhead deterministic exceptions: Throwing values: <a href="http://open-std.org/JTC1/SC22/WG21/docs/papers/2018/p0709r0.pdf">http://open-std.org/JTC1/SC22/WG21/docs/papers/2018/p0709r0.pdf</a><a href="#fnref4" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn5" role="doc-endnote"><p>Abbreviated Lambdas: <a href="http://www.open-std.or/jtc1/sc22/wg21/docs/papers/2017/p0573r2.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0573r2.html</a><a href="#fnref5" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn6" role="doc-endnote"><p>Barry Revzin blog: <a href="https://brevzin.github.io/c++/2020/01/15/abbrev-lambdas/">https://brevzin.github.io/c++/2020/01/15/abbrev-lambdas/</a><a href="#fnref6" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn7" role="doc-endnote"><p>Change scope of lambda trailing-return-type: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2036r1.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2036r1.html</a><a href="#fnref7" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn8" role="doc-endnote"><p>Lifting overload sets into function objects (2013) <a href="http://http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3617.htm">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3617.htm</a><a href="#fnref8" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn9" role="doc-endnote"><p>Overload sets as function arguments (2016) <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0119r2.pdf">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0119r2.pdf</a><a href="#fnref9" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn10" role="doc-endnote"><p>Lifting overload sets into objects (2017) <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0834r0.htm">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0834r0.htm</a><a href="#fnref10" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn11" role="doc-endnote"><p>Now I Am Become Perl (blog):<a href="https://vector-of-bool.github.io/2018/10/31/become-perl.html">https://vector-of-bool.github.io/2018/10/31/become-perl.html</a><a href="#fnref11" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn12" role="doc-endnote"><p>More flexible optional::value_or():<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2218r0.pdf">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2218r0.pdf</a><a href="#fnref12" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn13" role="doc-endnote"><p>auto(x): decay-copy in the language:<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0849r7.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0849r7.html</a><a href="#fnref13" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn14" role="doc-endnote"><p>SO Using member function in std::all_of:<a href="https://stackoverflow.com/a/58381525/362515">https://stackoverflow.com/a/58381525/362515</a><a href="#fnref14" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>
</div>
</div>
</body>
</html>
