<!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>Abbreviated Parameters</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">Abbreviated Parameters</h1>

<table style="border:none;float:right">
  <tr>
    <td>Document #: </td>
    <td>xxx</td>
  </tr>
  <tr>
    <td>Date: </td>
    <td>2021-19-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 alternative way of declaring parameter lists, one that let us omit parameter types.</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>
<p>Lambda expressions are often used in a specific context, which can be used to infer some of their required elements. Because of this, there is a strong desire to have the shortest possible form of such expressions. This resulted in few proposals, like for example <strong>Abbreviated Lambdas (P0573R2)<a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a></strong>. P0573R2 did not pass for few reasons,<a href="#fn2" class="footnote-ref" id="fnref2" role="doc-noteref"><sup>2</sup></a> here is a summary:</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>It is not hard to notice, two of the issue are related to the semantics of the Abbreviated Lambdas <strong>body</strong>, one is related to the <strong>parameters</strong>.<br />
This paper also makes the observation, often it is the params that are contributing to the verbosity of a lambda the most, if we focus on the day-to-day uses and not the “perfect forwarding” scenario:</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="op">[](</span><span class="kw">const</span> <span class="kw">auto</span><span class="op">&amp;</span> a, <span class="kw">const</span> <span class="kw">auto</span><span class="op">&amp;</span> b<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> a <span class="op">&lt;</span> b; <span class="op">}</span></span></code></pre></div>
<p><em>Parameter types dominate the lambda expression in common cases.</em></p>
<blockquote>
<p>An argument can be made, we could use <code>auto&amp;&amp;</code> and get rid of <code>const</code>, saving significant number of characters. This is not entirely true, because, <code>auto&amp;&amp;</code> will be a <code>const</code> reference only if the original object is <code>const</code>. <em>Most</em> of the times this is not true - the object is not <code>const</code>, yet we want to immutably operate on it. By using <code>auto&amp;&amp;</code> we would change the meaning of our lambda, no matter how we look at it.</p>
</blockquote>
<p>Interestingly, not only we will gain the most if we get rid of the types, sans “forwarding”, but it seems, the problems we had in attempt to do so are mostly technical - no easy way to differentiate b/w normal parameter list and one with no types. The <strong>body</strong> issues on the other hand are significantly more involved, while at the same time giving smaller verbosity reduction in day-to-day code.</p>
<p>This paper suggest splitting the issues in <strong>“body issue”</strong> and <strong>“params issue”</strong> and deals only with the latter.</p>
</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>Introduce a <em>slightly</em> different syntax to denote <strong>Abbreviated Parameters</strong>:</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="co">// lambda:</span></span>
<span id="cb2-2"><a href="#cb2-2"></a><span class="op">[]((</span>a, b<span class="op">))</span> <span class="op">{</span> <span class="cf">return</span> a <span class="op">&lt;</span> b; <span class="op">}</span></span>
<span id="cb2-3"><a href="#cb2-3"></a><span class="co">// function:</span></span>
<span id="cb2-4"><a href="#cb2-4"></a><span class="kw">auto</span> less_then<span class="op">((</span>a, b<span class="op">))</span> <span class="op">{</span> <span class="cf">return</span> a <span class="op">&lt;</span> b; <span class="op">}</span></span></code></pre></div>
<p><em>Double parenthesis indicated Abbreviated Parameters.</em></p>
<section id="details" data-number="3.1">
<h2 data-number="3.1"><span class="header-section-number">3.1</span> Details<a href="#details" class="self-link"></a></h2>
<p><strong>If an parameters list starts with double parentheses <code>((</code>, then all single identifier are <em>not</em> types, but variables instead:</strong></p>
<div class="sourceCode" id="cb3"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb3-1"><a href="#cb3-1"></a><span class="kw">auto</span> something<span class="op">(</span>string, vector<span class="op">)</span>;   <span class="co">//&lt; declaration of function with two parameters of type `string` and `vector`.</span></span>
<span id="cb3-2"><a href="#cb3-2"></a>                                  <span class="co">// param names are omitted</span></span>
<span id="cb3-3"><a href="#cb3-3"></a><span class="kw">auto</span> something<span class="op">((</span>string, vector<span class="op">))</span>; <span class="co">//&lt; declaration of function with two parameters of deduced type.</span></span>
<span id="cb3-4"><a href="#cb3-4"></a>                                  <span class="co">// param names are `string` and `vector` (this proposal)</span></span></code></pre></div>
<p>Using multiple identifiers results in exactly the same declarations no matter if single or double parentheses are used:</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> something<span class="op">(</span>vector v<span class="op">)</span>;   <span class="co">//&lt; same declarations</span></span>
<span id="cb4-2"><a href="#cb4-2"></a><span class="kw">auto</span> something<span class="op">((</span>vector v<span class="op">))</span>; <span class="co">//&lt;</span></span>
<span id="cb4-3"><a href="#cb4-3"></a><span class="kw">auto</span> something<span class="op">(</span><span class="kw">const</span> vector<span class="op">&amp;</span> v<span class="op">)</span>;   <span class="co">//&lt; same declarations</span></span>
<span id="cb4-4"><a href="#cb4-4"></a><span class="kw">auto</span> something<span class="op">((</span><span class="kw">const</span> vector<span class="op">&amp;</span> v<span class="op">))</span>; <span class="co">//&lt;</span></span></code></pre></div>
<p>Mixing single and multiple identifiers is possible:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb5-1"><a href="#cb5-1"></a><span class="kw">auto</span> something<span class="op">((</span>string, <span class="kw">const</span> vector<span class="op">&amp;</span> v<span class="op">))</span>; <span class="co">//&lt; `string` is of deduced type, `v` is of const vector&amp;</span></span></code></pre></div>
<p>In other words, <strong>types are optional</strong>. Parameters of deduced type are <strong>templated parameters</strong>. Functions and lambdas, containing such parameters are templates. The above declaration is equivalent to:</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb6-1"><a href="#cb6-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> T<span class="op">&gt;</span></span>
<span id="cb6-2"><a href="#cb6-2"></a><span class="kw">auto</span> something<span class="op">(</span>T <span class="op">&lt;</span>qualifiers<span class="op">&gt;</span> string, <span class="kw">const</span> vector<span class="op">&amp;</span> v<span class="op">)</span>;</span></code></pre></div>
<p><em>Function template. <code>&lt;qualifiers&gt;</code> are discussed in <strong>Part 2</strong>.</em></p>
<p>Mixing with regular template parameters is also possible:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb7-1"><a href="#cb7-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> T<span class="op">&gt;</span> <span class="dt">void</span> func<span class="op">((</span>T a, b<span class="op">))</span>; </span>
<span id="cb7-2"><a href="#cb7-2"></a><span class="op">[]&lt;</span><span class="kw">class</span> T<span class="op">&gt;((</span>T a, b<span class="op">))</span> <span class="op">{}</span>;               </span>
<span id="cb7-3"><a href="#cb7-3"></a></span>
<span id="cb7-4"><a href="#cb7-4"></a><span class="co">// equivalent to</span></span>
<span id="cb7-5"><a href="#cb7-5"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> T, <span class="kw">class</span> U<span class="op">&gt;</span> <span class="dt">void</span> func<span class="op">(</span>T a, U <span class="op">&lt;</span>qualifiers<span class="op">&gt;</span> b<span class="op">)</span>; </span>
<span id="cb7-6"><a href="#cb7-6"></a><span class="op">[]&lt;</span><span class="kw">class</span> T, <span class="kw">class</span> U<span class="op">&gt;(</span>T a, U <span class="op">&lt;</span>qualifiers<span class="op">&gt;</span> b<span class="op">)</span> <span class="op">{}</span>; </span></code></pre></div>
<p>As well as omitting identifiers, partially or completely:</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">void</span> func<span class="op">((</span>,<span class="op">))</span>;</span>
<span id="cb8-2"><a href="#cb8-2"></a><span class="op">[]((</span>a,,c,<span class="op">))</span> <span class="op">{}</span>; </span>
<span id="cb8-3"><a href="#cb8-3"></a></span>
<span id="cb8-4"><a href="#cb8-4"></a><span class="co">// equivalent to</span></span>
<span id="cb8-5"><a href="#cb8-5"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> T, <span class="kw">class</span> U<span class="op">&gt;</span> <span class="dt">void</span> func<span class="op">(</span>T <span class="op">&lt;</span>qualifiers<span class="op">&gt;</span>, U <span class="op">&lt;</span>qualifiers<span class="op">&gt;)</span>;</span>
<span id="cb8-6"><a href="#cb8-6"></a><span class="op">[](</span><span class="kw">auto</span> <span class="op">&lt;</span>qualifiers<span class="op">&gt;</span> a, <span class="kw">auto</span> <span class="op">&lt;</span>qualifiers<span class="op">&gt;</span>, <span class="kw">auto</span> <span class="op">&lt;</span>qualifiers<span class="op">&gt;</span> c, <span class="kw">auto</span> <span class="op">&lt;</span>qualifiers<span class="op">&gt;)</span> <span class="op">{}</span>; </span></code></pre></div>
<p>If there are no identifiers and no commas, the list is empty:</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="dt">void</span> func<span class="op">(())</span>;</span>
<span id="cb9-2"><a href="#cb9-2"></a></span>
<span id="cb9-3"><a href="#cb9-3"></a><span class="co">// equivalent to</span></span>
<span id="cb9-4"><a href="#cb9-4"></a><span class="dt">void</span> func<span class="op">()</span>;</span></code></pre></div>
<p>If the parameters list does not contain deduced types, or extra commas, the declaration is <em>not</em> a template:</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="dt">void</span> func<span class="op">((</span>T a, U b<span class="op">))</span>; </span>
<span id="cb10-2"><a href="#cb10-2"></a></span>
<span id="cb10-3"><a href="#cb10-3"></a><span class="co">// equivalent to</span></span>
<span id="cb10-4"><a href="#cb10-4"></a><span class="dt">void</span> func<span class="op">(</span>T a, U b<span class="op">)</span>; </span></code></pre></div>
<p>Default arguments can be supplied as usual:</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="dt">void</span> func<span class="op">((</span>a <span class="op">=</span> <span class="dv">12</span>, b <span class="op">=</span> <span class="st">&quot;hello&quot;</span><span class="bu">s</span><span class="op">))</span>; </span>
<span id="cb11-2"><a href="#cb11-2"></a></span>
<span id="cb11-3"><a href="#cb11-3"></a><span class="co">// equivalent to</span></span>
<span id="cb11-4"><a href="#cb11-4"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> T<span class="op">=</span><span class="dt">int</span>, <span class="kw">class</span> U<span class="op">=</span>std<span class="op">::</span>string<span class="op">&gt;</span> <span class="dt">void</span> func<span class="op">(</span>T <span class="op">&lt;</span>qualifiers<span class="op">&gt;</span> <span class="op">=</span> <span class="dv">12</span>, U <span class="op">&lt;</span>qualifiers<span class="op">&gt;</span> b <span class="op">=</span> <span class="st">&quot;hello&quot;</span><span class="bu">s</span><span class="op">)</span>;</span></code></pre></div>
<p>The syntax can not be used to declare function pointers or signatures:</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="co">// using FuncPtr = void(*)((string));                 // error</span></span>
<span id="cb12-2"><a href="#cb12-2"></a><span class="co">// using FuncPtr = void(*)((std::string));            // error</span></span>
<span id="cb12-3"><a href="#cb12-3"></a><span class="co">// using FuncPtr = void(*)((const std::string&amp;));     // error</span></span></code></pre></div>
<p>The main reason to disallow this is to be consistent with current <code>auto</code> rules:</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="co">// using FuncPtr = void(*)(auto); // already an error</span></span></code></pre></div>
<p>Although, it could be argued <code>auto</code> in <code>using</code> declaration can be allowed to mean a template param for the <code>using</code> declaration itself:</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">template</span><span class="op">&lt;</span><span class="kw">class</span> T<span class="op">&gt;</span></span>
<span id="cb14-2"><a href="#cb14-2"></a><span class="kw">using</span> FuncPtr <span class="op">=</span> <span class="dt">void</span><span class="op">(*)(</span>T<span class="op">)</span>;</span></code></pre></div>
<p>As this is completely out of scope for the current proposal, <strong>double parentheses are allowed only where <code>auto</code> placeholder is allowed</strong>.<br />
Similarly, <strong>function declarations inside a block are not allowed</strong> :</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">void</span> f<span class="op">()</span> </span>
<span id="cb15-2"><a href="#cb15-2"></a><span class="op">{</span></span>
<span id="cb15-3"><a href="#cb15-3"></a>  <span class="op">[]((</span>string<span class="op">)){}</span>;             <span class="co">//&lt; Lambda: OK</span></span>
<span id="cb15-4"><a href="#cb15-4"></a><span class="co">//  auto something((string)); //&lt; Function: error</span></span>
<span id="cb15-5"><a href="#cb15-5"></a><span class="op">}</span></span></code></pre></div>
<p>This should come to no surprise, because function templates in block scope are not possible today. However, even if we allow these, double parenths declarations will <em>still</em> be disallowed, because it will be a breaking change: <code>auto something((string));</code> is already a valid expression (a constructor call to <code>something</code> object, taking <code>string</code> variable as an argument).</p>
<p>This covers <strong>Part 1</strong> of the proposal - <strong>allow a 3th way of declaring function templates, one that will let us to omit the type (or its placeholder in the form of <code>auto</code>) completely</strong>. <strong>Part 2</strong> will discuss the options we have with regard to the deduced type and its decorations.</p>
</section>
<section id="example" data-number="3.2">
<h2 data-number="3.2"><span class="header-section-number">3.2</span> Example<a href="#example" class="self-link"></a></h2>
<p>As stated in the beginning, getting rid of the parameters type is one of the best “bang for the buck” in the attempt to lower verbosity:</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="co">// given</span></span>
<span id="cb16-2"><a href="#cb16-2"></a><span class="kw">struct</span> fruit <span class="op">{...}</span>;</span>
<span id="cb16-3"><a href="#cb16-3"></a>std<span class="op">::</span>vector<span class="op">&lt;</span>std<span class="op">::</span>string<span class="op">&gt;</span> fruits<span class="op">{</span><span class="st">&quot;apples&quot;</span>, <span class="st">&quot;oranges&quot;</span>,<span class="st">&quot;cherries&quot;</span><span class="op">}</span>;</span>
<span id="cb16-4"><a href="#cb16-4"></a>std<span class="op">::</span>vector<span class="op">&lt;</span>std<span class="op">::</span>vector<span class="op">&lt;</span>fruit<span class="op">&gt;&gt;</span> baskets<span class="op">{...}</span>;</span>
<span id="cb16-5"><a href="#cb16-5"></a></span>
<span id="cb16-6"><a href="#cb16-6"></a>std<span class="op">::</span>transform<span class="op">(</span>fruits<span class="op">.</span>begin<span class="op">()</span>, fruits<span class="op">.</span>end<span class="op">()</span>, baskets<span class="op">.</span>begin<span class="op">()</span>, fruits<span class="op">.</span>begin<span class="op">()</span>,</span>
<span id="cb16-7"><a href="#cb16-7"></a><span class="co">// from</span></span>
<span id="cb16-8"><a href="#cb16-8"></a>  <span class="op">[](</span><span class="kw">const</span> std<span class="op">::</span>string<span class="op">&amp;</span> fruit, <span class="kw">const</span> std<span class="op">::</span>vector<span class="op">&lt;</span>fruit<span class="op">&gt;&amp;</span> basket<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> fruit <span class="op">+</span> <span class="st">&quot;: &quot;</span> <span class="op">+</span> std<span class="op">::</span>to_string<span class="op">(</span>basket<span class="op">.</span>size<span class="op">())</span>; </span>
<span id="cb16-9"><a href="#cb16-9"></a><span class="co">// or</span></span>
<span id="cb16-10"><a href="#cb16-10"></a>  <span class="op">[](</span><span class="kw">const</span> <span class="kw">auto</span><span class="op">&amp;</span> fruit, <span class="kw">const</span> <span class="kw">auto</span><span class="op">&amp;</span> basket<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> fruit <span class="op">+</span> <span class="st">&quot;: &quot;</span> <span class="op">+</span> std<span class="op">::</span>to_string<span class="op">(</span>basket<span class="op">.</span>size<span class="op">())</span>; </span>
<span id="cb16-11"><a href="#cb16-11"></a><span class="co">// to (this proposal)</span></span>
<span id="cb16-12"><a href="#cb16-12"></a>  <span class="op">[]((</span>fruit, basket<span class="op">))</span> <span class="op">{</span> <span class="cf">return</span> fruit <span class="op">+</span> <span class="st">&quot;: &quot;</span> <span class="op">+</span> std<span class="op">::</span>to_string<span class="op">(</span>basket<span class="op">.</span>size<span class="op">())</span>;</span>
<span id="cb16-13"><a href="#cb16-13"></a><span class="op">})</span>;</span>
<span id="cb16-14"><a href="#cb16-14"></a></span>
<span id="cb16-15"><a href="#cb16-15"></a><span class="co">// `auto&amp;&amp;` is discussed in Part 2</span></span></code></pre></div>
<p>If we take a theoretical “abbreviated body”, the gains are much less in terms of reducing verbosity, at least in this example, though I would argue, the example is fairly representative in general:</p>
<div class="sourceCode" id="cb17"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb17-1"><a href="#cb17-1"></a>std<span class="op">::</span>transform<span class="op">(</span>fruits<span class="op">.</span>begin<span class="op">()</span>, fruits<span class="op">.</span>end<span class="op">()</span>, baskets<span class="op">.</span>begin<span class="op">()</span>, fruits<span class="op">.</span>begin<span class="op">()</span>,</span>
<span id="cb17-2"><a href="#cb17-2"></a>  <span class="op">[](</span><span class="kw">const</span> <span class="kw">auto</span><span class="op">&amp;</span> fruit, <span class="kw">const</span> <span class="kw">auto</span><span class="op">&amp;</span> basket<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> fruit <span class="op">+</span> <span class="st">&quot;: &quot;</span> <span class="op">+</span> std<span class="op">::</span>to_string<span class="op">(</span>basket<span class="op">.</span>size<span class="op">()</span>; </span>
<span id="cb17-3"><a href="#cb17-3"></a><span class="op">})</span>;</span>
<span id="cb17-4"><a href="#cb17-4"></a>std<span class="op">::</span>transform<span class="op">(</span>fruits<span class="op">.</span>begin<span class="op">()</span>, fruits<span class="op">.</span>end<span class="op">()</span>, baskets<span class="op">.</span>begin<span class="op">()</span>, fruits<span class="op">.</span>begin<span class="op">()</span>,</span>
<span id="cb17-5"><a href="#cb17-5"></a>  <span class="op">[](</span><span class="kw">const</span> <span class="kw">auto</span><span class="op">&amp;</span> fruit, <span class="kw">const</span> <span class="kw">auto</span><span class="op">&amp;</span> basket<span class="op">)</span> <span class="op">=&gt;</span> fruit <span class="op">+</span> <span class="st">&quot;: &quot;</span> <span class="op">+</span> std<span class="op">::</span>to_string<span class="op">(</span>basket<span class="op">.</span>size<span class="op">()</span> </span>
<span id="cb17-6"><a href="#cb17-6"></a><span class="op">)</span>;</span></code></pre></div>
<p>As you can see, <em>if we ignore the generic, forwarding case</em>, the gains are almost non-existent - <strong>a constant 7 characters total,</strong> 6 of them from <code>return</code>, 1 for the semicolon.<br />
This is not to say the generic case is to be ignored - quite the contrary. <em>Most</em> of the benefits in an “abbreviated lambdas” will come from a new, smarter “abbreviated body”. An “abbreviated body” will solve more problems then simply limiting verbosity as it will lower the complexity of advanced topics that only look simple on a first glance. This paper is <em><strong>not</strong></em> against any “abbreviated body” solutions and it does not block or contradict ony of them.<br />
In any case however, “abbreviated parameters” have enough practical benefit for “abbreviating” the lambda expression as a whole to be worth pursuing on their own.</p>
</section>
<section id="related-work" data-number="3.3">
<h2 data-number="3.3"><span class="header-section-number">3.3</span> Related Work<a href="#related-work" class="self-link"></a></h2>
<p>Using duplicated symbols to denote a different entity is not new. In fact, it can be traced back to (at least) <code>C</code>:</p>
<ul>
<li>We have <em>multiple</em> operators that have double versions <code>||</code>, <code>&amp;&amp;</code>, <code>++</code>, <code>--</code>, <code>&lt;&lt;</code>, <code>&gt;&gt;</code>, <code>==</code>;</li>
<li>We have two types of references, <code>&amp;</code> and <code>&amp;&amp;</code>, expressed via duplication of the symbol;</li>
<li>We have both lambda capture - <code>[something]</code> - and attributes - <code>[[something]]</code>;</li>
<li>We have both <code>:</code> and <code>::</code>;</li>
<li>We have <code>.</code> and <code>...</code>;</li>
</ul>
<p>I would argue, symbol duplications is at this point a natural way to introduce new meaning without new symbols.</p>
<section id="the-bigger-picture" data-number="3.3.1">
<h3 data-number="3.3.1"><span class="header-section-number">3.3.1</span> The bigger picture<a href="#the-bigger-picture" class="self-link"></a></h3>
<p>Although this proposal is focused on the parameters part of the function/lambda declaration, arguing for the benefits of its own, it can also be seen as enabler for the complete Abbreviated Lambda (P0573R2<a href="#fn3" class="footnote-ref" id="fnref3" role="doc-noteref"><sup>3</sup></a>) proposal as well. Recently there is a push to solve the 3th issue that prevented its adoption, the <strong>Mismatch between the trailing-return-type and the body</strong> part, with the introduction of <strong>p2036r1</strong>.<a href="#fn4" class="footnote-ref" id="fnref4" role="doc-noteref"><sup>4</sup></a> It proposes changing the return type parsing to be identical to function body parsing, negating the said issue.<br />
If current and the <strong>p2036r1</strong> proposals are accepted, we will have 2/3 issues solved, which is much, much better place to be!</p>
<p>Here is the place to emphasize, <strong>all</strong> modern languages, have <em>both</em> abbreviated params for lambdas and lambdas expression bodies:<br />
<strong>D, C#:</strong> <code>(x, y) =&gt; ...</code> , <strong>Java:</strong> <code>(x, y) -&gt; ...</code> , <strong>Rust:</strong> <code>|x, y| ...</code>, <strong>Kotlin:</strong> <code>{x, y -&gt; ...}</code>, <strong>Swift:</strong> <code>{x, y in ...}</code><br />
These are <em>non-functional</em>, <em>strongly-typed</em> languages, all agreeing types in this context serve little to no value while greatly increasing the visual clutter. For C++ it is no different.</p>
</section>
</section>
</section>
<section id="future-direction-not-proposed-for-now" data-number="4">
<h1 data-number="4"><span class="header-section-number">4</span> Future direction (not proposed for now)<a href="#future-direction-not-proposed-for-now" class="self-link"></a></h1>
<p>Interestingly, if the current proposal is applied to <code>range-for</code>, <em>it solves the main issue, which led to the rejection of the <code>for(elem : range)</code> syntax.</em><br />
The problem was that declarations like this can be misleading<a href="#fn5" class="footnote-ref" id="fnref5" role="doc-noteref"><sup>5</sup></a>:</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="dt">int</span> i;</span>
<span id="cb18-2"><a href="#cb18-2"></a><span class="cf">for</span><span class="op">(</span>i<span class="op">=</span><span class="dv">0</span>; i<span class="op">&lt;</span>size; i<span class="op">++)</span>     <span class="co">//&lt; these are different - reuse-vs-introduce</span></span>
<span id="cb18-3"><a href="#cb18-3"></a><span class="cf">for</span><span class="op">(</span><span class="dt">int</span> i<span class="op">=</span><span class="dv">0</span>; i<span class="op">&lt;</span>size; i<span class="op">++)</span> <span class="co">//&lt;</span></span>
<span id="cb18-4"><a href="#cb18-4"></a>something i;</span>
<span id="cb18-5"><a href="#cb18-5"></a><span class="cf">for</span><span class="op">(</span>i <span class="op">:</span> container<span class="op">)</span>     <span class="co">//&lt; are these different as well? </span></span>
<span id="cb18-6"><a href="#cb18-6"></a><span class="cf">for</span><span class="op">(</span><span class="dt">int</span> i <span class="op">:</span> container<span class="op">)</span> <span class="co">//&lt; </span></span></code></pre></div>
<p>Having a syntax that <em>already</em> means variable introduction (of deduced type) solves this issue completely:</p>
<div class="sourceCode" id="cb19"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb19-1"><a href="#cb19-1"></a>something i;</span>
<span id="cb19-2"><a href="#cb19-2"></a><span class="cf">for</span><span class="op">((</span>i <span class="op">:</span> container<span class="op">))</span>   <span class="co">//&lt; obviously an introduction</span></span>
<span id="cb19-3"><a href="#cb19-3"></a><span class="cf">for</span><span class="op">(</span><span class="dt">int</span> i <span class="op">:</span> container<span class="op">)</span></span></code></pre></div>
<p><em>Double parentheses <strong>always</strong> mean variable introduction.</em></p>
</section>
<section id="part-2" data-number="5">
<h1 data-number="5"><span class="header-section-number">5</span> Part 2<a href="#part-2" class="self-link"></a></h1>
<p>This part deals with what the actual deduced type should be.</p>
<p>The often regarded “right solution” for that is to use <code>auto&amp;&amp;</code> - it is what <strong>p0573</strong> suggested and was previously proposed for the <code>for(elem : list)</code> idea as well.<br />
This proposal argues against it, <em>though not strongly.</em> <strong>It is a valid option</strong> and the current proposal, at its core (Part 1), will be equally well served by any type deduction. With that out of the way, let’s see pros and cons of other options.</p>
<section id="downsides-of-auto" data-number="5.1">
<h2 data-number="5.1"><span class="header-section-number">5.1</span> Downsides of <code>auto&amp;&amp;</code><a href="#downsides-of-auto" class="self-link"></a></h2>
<section id="mutability" data-number="5.1.1">
<h3 data-number="5.1.1"><span class="header-section-number">5.1.1</span> Mutability<a href="#mutability" class="self-link"></a></h3>
<p>The single biggest downside of <code>auto&amp;&amp;</code> is its mutable reference semantics as default. These are not desirable defaults.<br />
Lets return to our fruits example:</p>
<div class="sourceCode" id="cb20"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb20-1"><a href="#cb20-1"></a>std<span class="op">::</span>transform<span class="op">(</span>fruits<span class="op">.</span>begin<span class="op">()</span>, fruits<span class="op">.</span>end<span class="op">()</span>, baskets<span class="op">.</span>begin<span class="op">()</span>, fruits<span class="op">.</span>begin<span class="op">()</span>,</span>
<span id="cb20-2"><a href="#cb20-2"></a>  <span class="op">[](</span><span class="kw">auto</span><span class="op">&amp;&amp;</span> fruit, <span class="kw">auto</span><span class="op">&amp;&amp;</span> basket<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> fruit <span class="op">+=</span> <span class="st">&quot;: &quot;</span> <span class="op">+</span> std<span class="op">::</span>to_string<span class="op">(</span>basket<span class="op">.</span>size<span class="op">())</span>;</span>
<span id="cb20-3"><a href="#cb20-3"></a><span class="op">})</span>;</span></code></pre></div>
<p>If the user incidentally assigns to <code>fruit</code>, it will break <code>std::transform</code> preconditions.<br />
It could be argued, the user can use <code>fruits.cbegin()</code> instead of <code>fruit.begin()</code>, but this requires <em>the same amount of attention</em> as writing <code>const</code> for the lambda params. If we talk about safe <em>default</em>, <code>auto&amp;&amp;</code> is not one.<br />
Besides in some cases <strong><code>cbegin()</code> is not even an option:</strong></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>sort<span class="op">(</span>fruits<span class="op">.</span>begin<span class="op">()</span>, fruits<span class="op">.</span>end<span class="op">()</span>,</span>
<span id="cb21-2"><a href="#cb21-2"></a>    <span class="op">[](</span><span class="kw">auto</span><span class="op">&amp;&amp;</span> lhs, <span class="kw">auto</span><span class="op">&amp;&amp;</span> rhs<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> lhs<span class="op">.</span>price<span class="op">()</span> <span class="op">&lt;</span> rhs<span class="op">.</span>price<span class="op">()</span>; <span class="op">}</span></span>
<span id="cb21-3"><a href="#cb21-3"></a><span class="op">)</span>;</span></code></pre></div>
<p>What if <code>price()</code> is not the correct method (or overload!) as it, for example, fetches price from an external source, does some other processing, and is undesirable in this context for performance or other reasons? We created a problem where there was none before. If this is example looks contrived, then why do we have <code>begin()</code> and <code>cbegin()</code> in the first place?</p>
<p>It gets even more interesting, if we take into account how predominant <code>const</code> lambdas are in practice. For example, <em>from all standard algorithms, <strong>only one</strong> is usable with mutating lambda - <code>for_each</code>!</em> Even if the algorithm itself is mutating, the function object itself is not, instead the return value is used to write to desired destination (either to the same container or not, resulting in either mutation or copy).</p>
<p>An argument can also be made about forwarding scenarios, where non-const ref-ref is the desired type. However, forwarding specifically is excursively a library/wrapper feature. These scenarios are by definition less common then “the general usage” - a “library” is meant for code-reuse, and code-reuse is “<em>write once</em>, reuse many times”. This is, the day-to-day usage of a language is always more common then writing a library for it.</p>
</section>
<section id="hidden-reference" data-number="5.1.2">
<h3 data-number="5.1.2"><span class="header-section-number">5.1.2</span> Hidden reference<a href="#hidden-reference" class="self-link"></a></h3>
<p>Using <code>auto&amp;&amp;</code> in the case of <code>[](a, b){}</code> (or <code>for(elem : list)</code> for that matter) creates non-obvious and arguably unexpected hidden reference.<br />
If we compare current syntax for</p>
<ul>
<li>variable: <code>int i</code></li>
<li>parameter: <code>void(int i)</code></li>
<li>capture: <code>[i]{}</code></li>
</ul>
<p>We never create reference, that is not explicitly marked in syntax:</p>
<ul>
<li>variable: <code>int&amp; i</code></li>
<li>parameter: <code>void(int&amp; i)</code></li>
<li>capture: <code>[&amp;i]{}</code></li>
</ul>
<p>Given this, <strong>what the expectations will be in this scenario</strong>:</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="op">[](</span>a, b<span class="op">){</span> a<span class="op">++</span>; b <span class="op">+=</span> a; <span class="cf">return</span> b;<span class="op">}</span></span></code></pre></div>
<p>Let’s be honest, <strong>no one would expect some far-away state is altered</strong>, <em>unless</em> he/she is <em>intimately</em> familiar with how are deduced types implemented. And it is not so obvious, not obvious at all. For example one might expect “behind the scenes” the declaration be in the form:</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="op">[](</span><span class="kw">auto</span> a, <span class="kw">auto</span> b<span class="op">){</span> a<span class="op">++</span>; b <span class="op">+=</span> a; <span class="cf">return</span> b;<span class="op">}</span></span></code></pre></div>
<p>This is not unreasonable assumption - after all <em>this is how capture works today</em> (mutability aside)! As said, one must have <em>intimate</em> knowledge to guess the answer.</p>
<p>Interestingly, or even ironically, the hidden nature of the reference works against the forwarding case as well:</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="op">[]((</span>a<span class="op">)){</span> <span class="cf">return</span> some_func<span class="op">(</span>std<span class="op">::</span>forward<span class="op">&lt;</span><span class="kw">decltype</span><span class="op">(</span>a<span class="op">)&gt;(</span>a<span class="op">))</span>; <span class="op">}</span></span></code></pre></div>
<p>Are we really doing forwarding here? How can one tell?<br />
Because there is no reference in sight, let alone a <code>&amp;&amp;</code> one, the user again must have intimate knowledge and trust, this works as expected - after all 1/2 visual hints that marks forwarding scenario is gone. And the hint that is removed is pretty important - only a specific type of reference is a forwarding one!</p>
</section>
<section id="verbose-to-get-const-back" data-number="5.1.3">
<h3 data-number="5.1.3"><span class="header-section-number">5.1.3</span> Verbose to get <code>const</code> back<a href="#verbose-to-get-const-back" class="self-link"></a></h3>
<p>If we consider immutability is always a good thing, how do we get it back?<br />
We either need full verbosity:</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="op">[](</span><span class="kw">const</span> <span class="kw">auto</span><span class="op">&amp;</span> a, <span class="kw">const</span> <span class="kw">auto</span><span class="op">&amp;</span> b<span class="op">){...}</span></span></code></pre></div>
<p>Or, well, partial verbosity, if we extend the possible definitions to allow “naked <code>const</code>”</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="op">[]((</span><span class="kw">const</span> a, <span class="kw">const</span> b<span class="op">)){...}</span></span></code></pre></div>
<p>Considering, for many types, we can just use non-reference <code>auto</code> today, we did not achieve much.</p>
<blockquote>
<p>For an <strong>Alternative solution</strong> see <strong>Appendix</strong>.</p>
</blockquote>
</section>
</section>
<section id="proposed-solution" data-number="5.2">
<h2 data-number="5.2"><span class="header-section-number">5.2</span> Proposed solution<a href="#proposed-solution" class="self-link"></a></h2>
<p>This paper suggests, a <strong>const reference</strong> and/or <strong>const copy</strong> as the best options for the deduced type.<br />
More specifically, <strong>const reference</strong> to be the default, but, <em>if deemed feasible</em>, <strong>allow optimizers to use copy instead</strong> for improved performance.</p>
<div class="sourceCode" id="cb27"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb27-1"><a href="#cb27-1"></a>std<span class="op">::</span>string s;</span>
<span id="cb27-2"><a href="#cb27-2"></a>std<span class="op">::</span>vector<span class="op">&lt;</span>std<span class="op">::</span>string<span class="op">&gt;</span> v;</span>
<span id="cb27-3"><a href="#cb27-3"></a></span>
<span id="cb27-4"><a href="#cb27-4"></a>std<span class="op">::</span>for_each<span class="op">(</span>s<span class="op">.</span>begin<span class="op">()</span>, s<span class="op">.</span>end<span class="op">()</span>, <span class="op">[]((</span>c<span class="op">)){</span> <span class="op">...</span> <span class="op">})</span>; <span class="co">//&lt; decltype(c) is `const char`</span></span>
<span id="cb27-5"><a href="#cb27-5"></a>std<span class="op">::</span>for_each<span class="op">(</span>v<span class="op">.</span>begin<span class="op">()</span>, v<span class="op">.</span>end<span class="op">()</span>, <span class="op">[]((</span>s<span class="op">)){</span> <span class="op">...</span> <span class="op">})</span>; <span class="co">//&lt; decltype(s) is `const std::sting&amp;`</span></span></code></pre></div>
<p>Because in both cases we are dealing with a <code>const</code> arg. the effect of the transformation to copy will be close to invisible to the user. The only observable side-effect will be if the user, or a subroutine, takes and stores the address of the argument, with the assumption, its lifetime is greater then the lambda itself. In that case the address can become invalid or not, depending on the argument type.<br />
How much this is a problem in practice is hard to jude, but this paper argues, it is extremely unlikely, a user will intentionally take the address of a param (or call a function which does so) AND use a signature, which does <em>not</em> have reference/pointer symbol on the param:</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="dt">void</span> func<span class="op">((</span>arg<span class="op">))</span> <span class="op">{</span> persistAddrOf<span class="op">(&amp;</span>arg<span class="op">)</span>; <span class="op">...</span> <span class="op">}</span> <span class="co">//&lt; Unrealistic scenario</span></span></code></pre></div>
<p><em>It is unlikely, the user expects, <code>arg</code> storage to outlive the call to <code>func</code>.</em></p>
<p>This goes back to the fact - there are no hidden references in C++. Sure, arg <em>could</em> be a reference, but no reason for the user to <em>expect</em> that. There is no previous experience to create such expectations!<br />
Also, the implementation can be such that, the user can query and/or assert if the conversion to reference will take place. Something along the lines of <code>static_assert(sizeof(arg) &lt; TO_CREF_THRESHOLD)</code>. This will allow 100% safe code, albeit with increased complexity.</p>
<p>Having said that, I do see this feature as potentially controversial, that is why, it is suggested only if feasible - <strong>const reference alone is good enough default</strong>. Besides, if the user wants to have a copy instead, a simple <code>auto</code> is still an option.</p>
<p>While on the subject of copying, why aren’t the arguments passed by copy, the way they are passed in functions and lambdas already, if there are no cvref decorations?<br />
There are multiple arguments against that.</p>
<ul>
<li>Expensive to copy big objects.</li>
<li>Verbose to get immutability back, even more so to get both reference <em>and</em> immutability.</li>
<li>Not really possible to implement “maybe-reference”, because this will change how the function/lambda works in a dangerous way. We can get away having “maybe-reference” exclusively because immutability, which makes the transformation safe, as long as one operates on the param alone, not its address.</li>
</ul>
<p>The pro-arguments are much weaker:</p>
<ul>
<li>No hidden immutability.</li>
<li>No hidden const reference.</li>
<li>No hidden change of param address. (In case “maybe-reference” is implemented)</li>
</ul>
<p>The first argument is weak, because we have a precedent with lambda captures. Captures can be though as “arguments, passed on lambda definition”. Not only that, but the immutability of lambdas has <em>overwillingly positive</em> reception in the community. In a way, by making the parameters of a lambda immutable, <em>we increase the overall consistency of the lambda expression as a whole</em> - now <em>all</em> arguments, passed to a lambda, either on definition or call time, are immutable.<br />
The second argument is also weak, because it does not affect how we write code - the reference is there purely for performance reasons, exactly how it is used today.<br />
The issue about param address is already discussed.</p>
<blockquote>
<p>A note about <strong>coroutines</strong>. This paper does not explore this space, but suggests, it is good idea to have different rules for deduction for coroutines. This is because references and coroutines do not match well. It looks like capture by copy to be much better option, however this is a separate discussion and <strong>for now coroutines should <em>not</em> support double parenths syntax.</strong> We simply don’t have enough experience with coroutines to be sure of the right defaults. Coroutines are significantly enough different, then either lambda or functions, and require a separate evaluation. Extending the current proposal can be done on later date.</p>
</blockquote>
<p>The above scenario handles “observation” functions only. If the user wants to modify the original argument passed (or want to ensure it has its address passed to the function), then using both <code>&amp;</code> or <code>&amp;&amp;</code> are proposed to serve these purposes:</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><span class="op">&amp;</span> incr<span class="op">((&amp;</span>src, delta<span class="op">))</span> <span class="op">{</span> <span class="cf">return</span> src <span class="op">+=</span> delta; <span class="op">}</span> <span class="co">//&lt; `src` is of type auto&amp;, `delta` is of type `const auto(&amp;)`</span></span>
<span id="cb29-2"><a href="#cb29-2"></a></span>
<span id="cb29-3"><a href="#cb29-3"></a><span class="op">[]((&amp;&amp;</span>a<span class="op">)){</span> <span class="cf">return</span> some_func<span class="op">(</span>std<span class="op">::</span>forward<span class="op">&lt;</span><span class="kw">decltype</span><span class="op">(</span>a<span class="op">)&gt;(</span>a<span class="op">))</span>; <span class="op">}</span> <span class="co">//&lt; `a` is of type auto&amp;&amp;</span></span></code></pre></div>
<p>By covering the 3 scenarios above (“observation”, “mutation”, “forwarding”) we solve all the issues listed above.</p>
<ul>
<li>Const is the default, matching the majority of cases and being the safest option.</li>
<li>No hidden reference*. Normal references are introduced as usual (matching the capture syntax completely). Forwarding references are clearly visible, as always. <em>At no point there is <strong>any</strong> potential confusion or uncertainty what the code does!</em></li>
<li>No hidden mutability, yet easy to introduce when needed, with a well know, minimal syntax.</li>
</ul>
<p>*The immutable reference is an implementation detail, an optimization, and is not <em>semantically</em> relevant.</p>
<p>In should be noted, so far <code>auto&amp;&amp;</code> as a default was ever only suggested in a very limited context - in a for-loop and lambdas (or lambda-like, single expression functions). Current proposal is not limited to those type of uses alone and anticipates typeless params potentially in normal functions as well. This changes the requirements a bit, as being able to express all common parameter usages (“observation”, “reference”, “forwarding”) is of much greater value. This is, while the niche use case of for-loop or lambda can be handled by one “good enough” type, a more universal support of deduced params require greater flexibility and expressiveness.<br />
For example, consider helper functions, local to a cpp file, or a private function in class. In these scenarios it is quite possible, the user might not use concepts to define such functions and opt for the “quick-and-dirty” approach as the functions are not really part of an API and the extra effort to “do it right” might not be worth it. Or may be this is a changing code, in a prototyping stage - the user is unsure what the requirements are. In these scenarios it will be highly unlikely, the “forwarding reference” to be the right type (even less so for all arguments!), and is quite likely, the user will want <em>some</em> control over the parameters, at least in terms of mutability:</p>
<div class="sourceCode" id="cb30"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb30-1"><a href="#cb30-1"></a><span class="kw">namespace</span> <span class="op">{</span></span>
<span id="cb30-2"><a href="#cb30-2"></a>  <span class="dt">void</span> assignPedalCrankFromRotorSpeed<span class="op">((&amp;</span>pedal, rotor<span class="op">))</span> <span class="op">{</span> pedal <span class="op">=</span> rotor <span class="op">/</span> CHAIN_FACTOR; <span class="op">}</span></span>
<span id="cb30-3"><a href="#cb30-3"></a>  <span class="op">...</span></span>
<span id="cb30-4"><a href="#cb30-4"></a><span class="op">}</span></span></code></pre></div>
<p><em>A local helper function</em></p>
<section id="pro-and-contra-auto" data-number="5.2.1">
<h3 data-number="5.2.1"><span class="header-section-number">5.2.1</span> Pro and Contra <code>auto&amp;&amp;</code><a href="#pro-and-contra-auto" class="self-link"></a></h3>
<p>As said in the beginning, <code>auto&amp;&amp;</code> is reasonable solution as well. Its main strength is its simplicity both in terms of definition and implementation, as well as the fact “it just works” in code. There is a charm to that.<br />
The “just works” part is considered especially relevant in cases where a mutating param must bind to a proxy object:</p>
<div class="sourceCode" id="cb31"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb31-1"><a href="#cb31-1"></a>std<span class="op">::</span>vector<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;</span>  vi<span class="op">(</span><span class="dv">10</span><span class="op">)</span>;</span>
<span id="cb31-2"><a href="#cb31-2"></a>std<span class="op">::</span>vector<span class="op">&lt;</span><span class="dt">bool</span><span class="op">&gt;</span> vb<span class="op">(</span><span class="dv">10</span><span class="op">)</span>;</span>
<span id="cb31-3"><a href="#cb31-3"></a>std<span class="op">::</span>for_each<span class="op">(</span>vi<span class="op">.</span>begin<span class="op">()</span>, vi<span class="op">.</span>end<span class="op">()</span>, <span class="op">[](</span><span class="kw">auto</span><span class="op">&amp;</span> v<span class="op">)</span> <span class="op">{</span> v <span class="op">=</span> <span class="dv">1</span>; <span class="op">})</span>;    <span class="co">//&lt; works</span></span>
<span id="cb31-4"><a href="#cb31-4"></a>std<span class="op">::</span>for_each<span class="op">(</span>vb<span class="op">.</span>begin<span class="op">()</span>, vb<span class="op">.</span>end<span class="op">()</span>, <span class="op">[](</span><span class="kw">auto</span><span class="op">&amp;</span> v<span class="op">)</span> <span class="op">{</span> v <span class="op">=</span> <span class="kw">true</span>; <span class="op">})</span>; <span class="co">//&lt; fails: MUST be auto&amp;&amp;</span></span></code></pre></div>
<p>There is no denying, “it will be nice” to be able to write a minimal expression, which will work in both cases, even more so, considering the cases where proxy objects are used are expected to increase somewhat with <code>ranges</code>.<br />
However, this is only true from <em>modifiable</em> references, <em>normal observation works with no added verbosity:</em></p>
<div class="sourceCode" id="cb32"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb32-1"><a href="#cb32-1"></a>std<span class="op">::</span>vector<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;</span>  vi<span class="op">(</span><span class="dv">10</span><span class="op">)</span>;</span>
<span id="cb32-2"><a href="#cb32-2"></a>std<span class="op">::</span>vector<span class="op">&lt;</span><span class="dt">bool</span><span class="op">&gt;</span> vb<span class="op">(</span><span class="dv">10</span><span class="op">)</span>;</span>
<span id="cb32-3"><a href="#cb32-3"></a>std<span class="op">::</span>for_each<span class="op">(</span>vi<span class="op">.</span>begin<span class="op">()</span>, vi<span class="op">.</span>end<span class="op">()</span>, <span class="op">[]((</span>v<span class="op">))</span> <span class="op">{</span> <span class="cf">if</span><span class="op">(</span>v <span class="op">==</span> <span class="dv">1</span><span class="op">)</span> <span class="op">...</span> ; <span class="op">})</span>;    <span class="co">//&lt; works with current proposal as well</span></span>
<span id="cb32-4"><a href="#cb32-4"></a>std<span class="op">::</span>for_each<span class="op">(</span>vb<span class="op">.</span>begin<span class="op">()</span>, vb<span class="op">.</span>end<span class="op">()</span>, <span class="op">[]((</span>v<span class="op">))</span> <span class="op">{</span> <span class="cf">if</span><span class="op">(</span>v <span class="op">==</span> <span class="kw">true</span><span class="op">)</span> <span class="op">...</span>; <span class="op">})</span>;  <span class="co">//&lt; </span></span></code></pre></div>
<p>This leaves us back to the fundamental question: <strong>Is it worth trading const?</strong> Consider:</p>
<div class="sourceCode" id="cb33"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb33-1"><a href="#cb33-1"></a>std<span class="op">::</span>vector<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;</span>  vi<span class="op">(</span><span class="dv">10</span><span class="op">)</span>;</span>
<span id="cb33-2"><a href="#cb33-2"></a>std<span class="op">::</span>vector<span class="op">&lt;</span><span class="dt">bool</span><span class="op">&gt;</span> vb<span class="op">(</span><span class="dv">10</span><span class="op">)</span>;</span>
<span id="cb33-3"><a href="#cb33-3"></a>std<span class="op">::</span>for_each<span class="op">(</span>vi<span class="op">.</span>begin<span class="op">()</span>, vi<span class="op">.</span>end<span class="op">()</span>, <span class="op">[]((</span>v<span class="op">))</span> <span class="op">{</span> <span class="cf">if</span><span class="op">(</span>v <span class="op">=</span> <span class="dv">1</span><span class="op">)</span> <span class="op">...</span> ; <span class="op">})</span>;    <span class="co">//&lt; &quot;just works&quot;?</span></span>
<span id="cb33-4"><a href="#cb33-4"></a>std<span class="op">::</span>for_each<span class="op">(</span>vb<span class="op">.</span>begin<span class="op">()</span>, vb<span class="op">.</span>end<span class="op">()</span>, <span class="op">[]((</span>v<span class="op">))</span> <span class="op">{</span> <span class="cf">if</span><span class="op">(</span>v <span class="op">=</span> <span class="kw">true</span><span class="op">)</span> <span class="op">...</span>; <span class="op">})</span>;  <span class="co">//&lt; </span></span></code></pre></div>
<p>Do we want to drop safer code for more “easy” one? Do we want to <strong>not</strong> guard against the above code, so that we can have “nice, universal syntax” <em>in the limited context of mutation <strong>alone</strong></em>? It is an honest question, and although this paper argues for const, the opposite still has merit.</p>
<p>Related to that also is the question, <strong>do we want less clear code if favor of marginally less verbose.</strong><br />
Is this <strong>“better”:</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="op">[]((</span>a<span class="op">)){</span> <span class="cf">return</span> some_func<span class="op">(</span>std<span class="op">::</span>forward<span class="op">&lt;</span><span class="kw">decltype</span><span class="op">(</span>a<span class="op">)&gt;(</span>a<span class="op">))</span>; <span class="op">}</span></span></code></pre></div>
<p>then</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="op">[]((&amp;&amp;</span>a<span class="op">)){</span> <span class="cf">return</span> some_func<span class="op">(</span>std<span class="op">::</span>forward<span class="op">&lt;</span><span class="kw">decltype</span><span class="op">(</span>a<span class="op">)&gt;(</span>a<span class="op">))</span>; <span class="op">}</span></span></code></pre></div>
<ul>
<li>Is it “better” to forward an argument that is not decorated with <code>&amp;&amp;</code>?<br />
</li>
<li>Do the <code>&amp;&amp;</code> “tip the scale” and make the declaration “verbose”?</li>
</ul>
<p>This paper expresses doubt. Where <code>auto</code> gives no additional information and can be cut out, <code>&amp;&amp;</code> <em>does</em> convey information!<br />
Of course “people will learn”, but it is not that simple. Where now (with <code>&amp;&amp;</code>) one can instantly see what kind of function he/she is dealing with (is it forwarding or not), when there is no such indication, all bets are off until the entire body is read:</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">auto</span> function<span class="op">((</span>a, b, c<span class="op">))</span> <span class="op">{</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="co">// 10 lines later</span></span>
<span id="cb36-4"><a href="#cb36-4"></a>  something<span class="op">(</span>a<span class="op">)</span>;</span>
<span id="cb36-5"><a href="#cb36-5"></a>  <span class="op">...</span></span>
<span id="cb36-6"><a href="#cb36-6"></a>  <span class="co">// another 20 lines</span></span>
<span id="cb36-7"><a href="#cb36-7"></a>  other_thing<span class="op">(</span>std<span class="op">::</span>forward<span class="op">&lt;</span>B<span class="op">&gt;(</span>b<span class="op">))</span>; </span>
<span id="cb36-8"><a href="#cb36-8"></a>  <span class="op">...</span></span>
<span id="cb36-9"><a href="#cb36-9"></a>  <span class="co">// yet another 30 lines</span></span>
<span id="cb36-10"><a href="#cb36-10"></a>  <span class="cf">return</span> do_it<span class="op">(</span>std<span class="op">::</span>forward<span class="op">&lt;</span>C<span class="op">&gt;(</span>c<span class="op">))</span>;</span>
<span id="cb36-11"><a href="#cb36-11"></a><span class="op">}</span></span></code></pre></div>
<p>What are the chances, later a colleague comes in and:</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="op">...</span></span>
<span id="cb37-2"><a href="#cb37-2"></a>  <span class="co">// another 20 lines</span></span>
<span id="cb37-3"><a href="#cb37-3"></a>  other_thing<span class="op">(</span>std<span class="op">::</span>forward<span class="op">&lt;</span>B<span class="op">&gt;(</span>b<span class="op">))</span>; </span>
<span id="cb37-4"><a href="#cb37-4"></a>  <span class="op">...</span></span>
<span id="cb37-5"><a href="#cb37-5"></a>  <span class="co">// yet another 30 lines</span></span>
<span id="cb37-6"><a href="#cb37-6"></a>  c<span class="op">.</span>omn<span class="op">(</span>b<span class="op">)</span>; <span class="co">//&lt; ok?</span></span>
<span id="cb37-7"><a href="#cb37-7"></a>  <span class="op">...</span></span>
<span id="cb37-8"><a href="#cb37-8"></a>  <span class="cf">return</span> do_it<span class="op">(</span>std<span class="op">::</span>forward<span class="op">&lt;</span>C<span class="op">&gt;(</span>c<span class="op">))</span>;</span>
<span id="cb37-9"><a href="#cb37-9"></a><span class="op">}</span></span></code></pre></div>
<p><em>What if <code>b</code> is moved by <code>forward</code>? Did the colleague noticed the <code>forward</code> at all, somewhere in the middle of the function?</em></p>
<p>Mistakes like this are best handled by static analysis for sure, but having more expressive parameters does not hurt either:</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="kw">auto</span> function<span class="op">((</span>a, <span class="op">&amp;&amp;</span>b, <span class="op">&amp;&amp;</span>c<span class="op">))</span> <span class="op">{</span> <span class="co">//&lt; obviously not just observing</span></span>
<span id="cb38-2"><a href="#cb38-2"></a>  <span class="op">...</span></span>
<span id="cb38-3"><a href="#cb38-3"></a><span class="op">}</span></span></code></pre></div>
<p><em>The <code>&amp;&amp;</code> is a clear hint, there might be forward at some point!</em></p>
<p>Less is not always more.</p>
</section>
<section id="summary" data-number="5.2.2">
<h3 data-number="5.2.2"><span class="header-section-number">5.2.2</span> Summary<a href="#summary" class="self-link"></a></h3>
<div class="columns">
<div class="column" style="width:50%;">
<p><strong>default to <code>auto&amp;&amp;</code></strong></p>
<p>+ Simple implementation<br />
+ Universal use in all cases<br />
+ Minimal verbosity</p>
<p>- Less safe (or more verbose)<br />
- Less clear<br />
- Learning curve for confident use</p>
</div><div class="column" style="width:50%;">
<p><strong>default to <code>const auto(&amp;)</code>, allow <code>&amp;</code> and <code>&amp;&amp;</code></strong></p>
<p>+ More safe<br />
+ More clear<br />
+ More control<br />
+ Minimal-to-No learning curve, consistent with current practices overall<br />
+ (Better performance if conversion to <code>const auto</code> is feasible)</p>
<p>- More involved implementation<br />
- Marginally more verbose <em>in some cases</em><br />
- “Pedantic”?<br />
- (Even more involved with <code>const auto</code> conversion)</p>
</div>
</div>
<p>The above summary shows, no solution is really “better” - there are trade-offs in both cases.<br />
This paper only hopes, we make the most informed decision when choosing one trade-off over another.</p>
</section>
</section>
</section>
<section id="appendix" data-number="6">
<h1 data-number="6"><span class="header-section-number">6</span> Appendix<a href="#appendix" class="self-link"></a></h1>
<section id="alternative-solution" data-number="6.1">
<h2 data-number="6.1"><span class="header-section-number">6.1</span> Alternative solution<a href="#alternative-solution" class="self-link"></a></h2>
<p>The <code>auto&amp;&amp;</code> vs <code>const auto&amp;</code> debade can change considerably if the core of the proposal (Part 1) is extended to allow specifying mutability for all arguments:</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">void</span> function<span class="op">((</span>a, b<span class="op">)</span><span class="kw">const</span><span class="op">)</span>; <span class="co">//&lt; All arguments are immutable</span></span></code></pre></div>
<p>This shifts the optics about using <code>auto&amp;&amp;</code> as it becomes easier to gain immutability (as well as potential “maybe-reference” implementation).<br />
Having such option does not contradict the const reference default as proposed, but makes many aspects of it redundant, like for example allowing <code>&amp;</code> and <code>&amp;&amp;</code> syntax:</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="dt">void</span> function<span class="op">((&amp;</span>a, <span class="op">&amp;</span>b<span class="op">)</span><span class="kw">const</span><span class="op">)</span>; <span class="co">//&lt; redundant with `const auto&amp;` default</span></span></code></pre></div>
<p>Some of the arguments pro explicit references still stand, but are greatly dampened, that is way this is more of an “Alternative solution”, not an “extension” - const ref default + parenth-const is <em>not</em> propsed.<br />
Parenth-const creates some interesting possibilities, unrelated to abbreviated parameters, like allowing us to have all-const parameters in normal functions:</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="dt">void</span> function<span class="op">((</span>std<span class="op">::</span>string<span class="op">&amp;</span> s, std<span class="op">::</span>vector<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;&gt;&amp;</span> v, <span class="dt">int</span> i<span class="op">)</span> <span class="kw">const</span> <span class="op">)</span>; <span class="co">//&lt; all arguments are immutable</span></span>
<span id="cb41-2"><a href="#cb41-2"></a><span class="co">//And/Or may be const in front</span></span>
<span id="cb41-3"><a href="#cb41-3"></a><span class="dt">void</span> function<span class="op">(</span><span class="kw">const</span><span class="op">(</span>std<span class="op">::</span>string<span class="op">&amp;</span> s, std<span class="op">::</span>vector<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;&gt;&amp;</span> v, <span class="dt">int</span> i<span class="op">))</span>; <span class="co">//&lt; all arguments are immutable</span></span></code></pre></div>
<p>As you can see, no abbreviated parameters in sight - we only take advantage of having to type just one <code>const</code> for all params. Of course, the value of this feature greatly depends on the number of parameters (and if we have a mix of const and non-const params), but is interesting nevertheless.</p>
<p>Arguably, the most interesting results are when this is applied to the theoretical <code>for-range</code> extension:</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="co">// `auto&amp;&amp;` is the default + parenth-const + range-for extension</span></span>
<span id="cb42-2"><a href="#cb42-2"></a></span>
<span id="cb42-3"><a href="#cb42-3"></a><span class="cf">for</span><span class="op">((</span>e <span class="op">:</span> list<span class="op">)</span><span class="kw">const</span><span class="op">)</span>  <span class="co">//&lt; some verbosity for observation, but clear and safer</span></span>
<span id="cb42-4"><a href="#cb42-4"></a></span>
<span id="cb42-5"><a href="#cb42-5"></a><span class="co">// equivalent to</span></span>
<span id="cb42-6"><a href="#cb42-6"></a><span class="cf">for</span><span class="op">(</span><span class="kw">const</span> <span class="kw">auto</span><span class="op">&amp;&amp;</span> e <span class="op">:</span> std<span class="op">::</span>as_const<span class="op">(</span>list<span class="op">))</span> <span class="co">//&lt; and immutable container!</span></span>
<span id="cb42-7"><a href="#cb42-7"></a></span>
<span id="cb42-8"><a href="#cb42-8"></a><span class="cf">for</span><span class="op">((</span>e <span class="op">:</span> list<span class="op">))</span> <span class="co">//&lt;  minimal-verbosity mutation and universal</span></span>
<span id="cb42-9"><a href="#cb42-9"></a></span>
<span id="cb42-10"><a href="#cb42-10"></a><span class="co">// equivalent to</span></span>
<span id="cb42-11"><a href="#cb42-11"></a><span class="cf">for</span><span class="op">(</span><span class="kw">auto</span><span class="op">&amp;&amp;</span> e <span class="op">:</span> list<span class="op">)</span></span></code></pre></div>
<p>As shown, this could solve the age-old problem where the list itself is not immutable, leading to undesired side-effects in some situations like when used with ref-counted containers.</p>
<p>Should be noted, when <code>e</code> is by default deduced to <code>const auto&amp;</code> we can simply re-define the expression to have immutable container, if there is no reference on the element variable. In other words, we can get this feature (a const container) <strong>for free</strong>, because of the immutable default. The downside is that we lose minimal-verbosity mutation and we have to use <code>&amp;&amp;</code> to be universal.</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="co">// `const auto&amp;` is default _alone_ + range-for extension</span></span>
<span id="cb43-2"><a href="#cb43-2"></a></span>
<span id="cb43-3"><a href="#cb43-3"></a><span class="cf">for</span><span class="op">((</span>e <span class="op">:</span> list<span class="op">))</span> <span class="co">//&lt; minimal-verbosity observation</span></span>
<span id="cb43-4"><a href="#cb43-4"></a></span>
<span id="cb43-5"><a href="#cb43-5"></a><span class="co">// equivalent to</span></span>
<span id="cb43-6"><a href="#cb43-6"></a><span class="cf">for</span><span class="op">(</span><span class="kw">const</span> <span class="kw">auto</span><span class="op">&amp;</span> e <span class="op">:</span> std<span class="op">::</span>as_const<span class="op">(</span>list<span class="op">))</span> <span class="co">//&lt; and immutable container!</span></span>
<span id="cb43-7"><a href="#cb43-7"></a></span>
<span id="cb43-8"><a href="#cb43-8"></a><span class="cf">for</span><span class="op">((&amp;&amp;</span>e <span class="op">:</span> list<span class="op">))</span> <span class="co">//&lt; to be universal, we need &amp;&amp;</span></span>
<span id="cb43-9"><a href="#cb43-9"></a></span>
<span id="cb43-10"><a href="#cb43-10"></a><span class="co">// equivalent to</span></span>
<span id="cb43-11"><a href="#cb43-11"></a><span class="cf">for</span><span class="op">(</span><span class="kw">auto</span><span class="op">&amp;&amp;</span> e <span class="op">:</span> list<span class="op">)</span></span></code></pre></div>
<section id="why-this-auto-is-not-the-primary-proposal" data-number="6.1.1">
<h3 data-number="6.1.1"><span class="header-section-number">6.1.1</span> Why this + <code>auto&amp;&amp;</code> is not the primary proposal?<a href="#why-this-auto-is-not-the-primary-proposal" class="self-link"></a></h3>
<p>- More verbose for the common, observation case.<br />
- Hidden mutable reference is still the default!<br />
- Introduces more new rules - not exactly a “natural extension” of preceding art.</p>
<p>~ Interesting, but questionable value outside abbreviated parameters. My be with the exception of <code>range-for</code>?</p>
<p>+ Allows all mutating cases to be at minimal-verbosity possible.<br />
+ Simpler, no need to introduce both <code>&amp;</code> and <code>&amp;&amp;</code>.</p>
<p>Unsurprisingly the value of the alternative solution relies once again on how we much we value immutability and what price we want to pay for it.<br />
Do we want default const and can live with “references noise” when modifying or want clear code when modifying and have const as an explicit opt-in, with the usual verbosity that comes with it.</p>
</section>
</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>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="#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>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="#fnref4" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn5" role="doc-endnote"><p>range-for discussion: <a href="https://groups.google.com/a/isocpp.org/g/std-proposals/c/nKRCQVvCxD8">https://groups.google.com/a/isocpp.org/g/std-proposals/c/nKRCQVvCxD8</a><a href="#fnref5" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>
</div>
</div>
</body>
</html>
