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

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

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

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

code.sourceCode > span { display: inline; }
</style>
  <style type="text/css">code ins { border: 1px solid #B3EBB3; padding-bottom: 1px; }
code del { border: 1px solid #ECB3C7; }
div.std blockquote { color: #000000; background-color: #F1F1F1;
border: 1px solid #D1D1D1;
padding-left: 0.5em; padding-right: 0.5em; }
div.std.ins blockquote { text-decoration: underline;
color: #000000; background-color: #C8FFC8;
border: 1px solid #B3EBB3; }
div.std.del blockquote { text-decoration: line-through;
color: #000000; background-color: #FFC8EB;
border: 1px solid #ECB3C7; }
div.std blockquote ins { text-decoration: underline;
color: #000000; background-color: #C8FFC8;
border: none; }
div.std blockquote del { text-decoration: line-through;
color: #000000; background-color: #FFC8EB;
border: none; }
div.std div.ins { text-decoration: underline;
color: #000000; background-color: #C8FFC8; }
div.std div.del { text-decoration: line-through;
color: #000000; background-color: #FFC8EB; }
div.std blockquote code * { color: #000000; }
div.std div.sourceCode { background-color: inherit; margin-left: 1em; }
div.std div.ins div.sourceCode * { text-decoration: underline; }
div.std div.del div.sourceCode * { text-decoration: line-through; }
div.std.ins div.sourceCode * { text-decoration: underline; }
div.std.del div.sourceCode * { text-decoration: line-through; }

.footnote { font-size: inherit;
margin-left: 0;
margin-right: 0;
margin-top: 0;
margin-bottom: 0;
}
</style>
  <link href="data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAVoJEAN6CRADegkQAWIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wCCRAAAgkQAAIJEAACCRAAsgkQAvoJEAP+CRAD/gkQA/4JEAP+CRADAgkQALoJEAACCRAAAgkQAAP///wD///8AgkQAAIJEABSCRACSgkQA/IJEAP99PQD/dzMA/3czAP99PQD/gkQA/4JEAPyCRACUgkQAFIJEAAD///8A////AHw+AFiBQwDqgkQA/4BBAP9/PxP/uZd6/9rJtf/bybX/upd7/39AFP+AQQD/gkQA/4FDAOqAQgBc////AP///wDKklv4jlEa/3o7AP+PWC//8+3o///////////////////////z7un/kFox/35AAP+GRwD/mVYA+v///wD///8A0Zpk+NmibP+0d0T/8evj///////+/fv/1sKz/9bCs//9/fr//////+/m2/+NRwL/nloA/5xYAPj///8A////ANKaZPjRmGH/5cKh////////////k149/3UwAP91MQD/lmQ//86rhv+USg3/m1YA/5hSAP+bVgD4////AP///wDSmmT4zpJY/+/bx///////8+TV/8mLT/+TVx//gkIA/5lVAP+VTAD/x6B//7aEVv/JpH7/s39J+P///wD///8A0ppk+M6SWP/u2sf///////Pj1f/Nj1T/2KFs/8mOUv+eWhD/lEsA/8aee/+0glT/x6F7/7J8Rvj///8A////ANKaZPjRmGH/48Cf///////+/v7/2qt//82PVP/OkFX/37KJ/86siv+USg7/mVQA/5hRAP+bVgD4////AP///wDSmmT40ppk/9CVXP/69O////////7+/v/x4M//8d/P//7+/f//////9u7n/6tnJf+XUgD/nFgA+P///wD///8A0ppk+NKaZP/RmWL/1qNy//r07///////////////////////+vXw/9akdP/Wnmn/y5FY/6JfFvj///8A////ANKaZFTSmmTo0ppk/9GYYv/Ql1//5cWm//Hg0P/x4ND/5cWm/9GXYP/RmGH/0ppk/9KaZOjVnmpY////AP///wDSmmQA0ppkEtKaZI7SmmT60ppk/9CWX//OkVb/zpFW/9CWX//SmmT/0ppk/NKaZJDSmmQS0ppkAP///wD///8A0ppkANKaZADSmmQA0ppkKtKaZLrSmmT/0ppk/9KaZP/SmmT/0ppkvNKaZCrSmmQA0ppkANKaZAD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkUtKaZNzSmmTc0ppkVNKaZADSmmQA0ppkANKaZADSmmQA////AP5/AAD4HwAA4AcAAMADAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAMADAADgBwAA+B8AAP5/AAAoAAAAIAAAAEAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wCCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAAyCRACMgkQA6oJEAOqCRACQgkQAEIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wD///8A////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRABigkQA5oJEAP+CRAD/gkQA/4JEAP+CRADqgkQAZoJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAAD///8A////AP///wD///8AgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAA4gkQAwoJEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQAxIJEADyCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAP///wD///8A////AP///wCCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAWgkQAmIJEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAJyCRAAYgkQAAIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wD///8A////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAdIJEAPCCRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAPSCRAB4gkQAAIJEAACCRAAAgkQAAIJEAAD///8A////AP///wD///8AgkQAAIJEAACCRAAAgkQASoJEANKCRAD/gkQA/4JEAP+CRAD/g0YA/39AAP9zLgD/bSQA/2shAP9rIQD/bSQA/3MuAP9/PwD/g0YA/4JEAP+CRAD/gkQA/4JEAP+CRADUgkQAToJEAACCRAAAgkQAAP///wD///8A////AP///wB+PwAAgkUAIoJEAKiCRAD/gkQA/4JEAP+CRAD/hEcA/4BBAP9sIwD/dTAA/5RfKv+viF7/vp56/76ee/+wiF7/lWAr/3YxAP9sIwD/f0AA/4RHAP+CRAD/gkQA/4JEAP+CRAD/gkQArIJEACaBQwAA////AP///wD///8A////AIBCAEBzNAD6f0EA/4NFAP+CRAD/gkQA/4VIAP92MwD/bSUA/6N1Tv/ezsL/////////////////////////////////38/D/6V3Uv9uJgD/dTEA/4VJAP+CRAD/gkQA/4JEAP+BQwD/fUAA/4FDAEj///8A////AP///wD///8AzJRd5qBlKf91NgD/dDUA/4JEAP+FSQD/cy4A/3YyAP/PuKP//////////////////////////////////////////////////////9K7qP94NQD/ciwA/4VJAP+CRAD/fkEA/35BAP+LSwD/mlYA6v///wD///8A////AP///wDdpnL/4qx3/8KJUv+PUhf/cTMA/3AsAP90LgD/4dK+/////////////////////////////////////////////////////////////////+TYxf91MAD/dTIA/31CAP+GRwD/llQA/6FcAP+gWwD8////AP///wD///8A////ANGZY/LSm2X/4ap3/92mcP+wdT3/byQA/8mwj////////////////////////////////////////////////////////////////////////////+LYxv9zLgP/jUoA/59bAP+hXAD/nFgA/5xYAPL///8A////AP///wD///8A0ppk8tKaZP/RmWL/1p9q/9ubXv/XqXj////////////////////////////7+fD/vZyG/6BxS/+gcUr/vJuE//r37f//////////////////////3MOr/5dQBf+dVQD/nVkA/5xYAP+cWAD/nFgA8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/SmWP/yohJ//jo2P//////////////////////4NTG/4JDFf9lGAD/bSQA/20kAP9kGAD/fz8S/+Xb0f//////5NG9/6txN/+LOgD/m1QA/51aAP+cWAD/m1cA/5xYAP+cWADy////AP///wD///8A////ANKaZPLSmmT/0ppk/8+TWf/Unmv//v37//////////////////////+TWRr/VwsA/35AAP+ERgD/g0UA/4JGAP9lHgD/kFga/8KXX/+TRwD/jT4A/49CAP+VTQD/n10A/5xYAP+OQQD/lk4A/55cAPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/y4tO/92yiP//////////////////////8NnE/8eCQP+rcTT/ez0A/3IyAP98PgD/gEMA/5FSAP+USwD/jj8A/5lUAP+JNwD/yqV2/694Mf+HNQD/jkAA/82rf/+laBj/jT4A8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/LiUr/4byY///////////////////////gupX/0I5P/+Wuev/Lklz/l1sj/308AP+QSwD/ol0A/59aAP+aVQD/k0oA/8yoh///////+fXv/6pwO//Lp3v///////Pr4f+oay7y////AP///wD///8A////ANKaZPLSmmT/0ppk/8uJSv/hvJj//////////////////////+G7l//Jhkb/0ppk/96nc//fqXX/x4xO/6dkFP+QSQD/llEA/5xXAP+USgD/yaOA///////38uv/qG05/8ijdv//////8efb/6ZpLPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/zIxO/9yxh///////////////////////7dbA/8iEQf/Sm2X/0Zlj/9ScZv/eqHf/2KJv/7yAQf+XTgD/iToA/5lSAP+JNgD/yKFv/611LP+HNQD/jT8A/8qmeP+kZRT/jT4A8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/Pk1n/1J5q//78+//////////////////+/fv/1aFv/8iEQv/Tm2b/0ppl/9GZY//Wn2z/1pZc/9eldf/Bl2b/kUcA/4w9AP+OQAD/lUwA/59eAP+cWQD/jT8A/5ZOAP+eXADy////AP///wD///8A////ANKaZPLSmmT/0ppk/9KZY//KiEn/8d/P///////////////////////47+f/05tm/8iCP//KiEj/yohJ/8eCP//RmGH//vfy///////n1sP/rXQ7/4k4AP+TTAD/nVoA/5xYAP+cVwD/nFgA/5xYAPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/0ptl/8uLTf/aq37////////////////////////////+/fz/6c2y/961jv/etY7/6Myx//78+v//////////////////////3MWv/5xXD/+ORAD/mFQA/51ZAP+cWAD/nFgA8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/SmmT/0ppk/8mFRP/s1b//////////////////////////////////////////////////////////////////////////////+PD/0JFU/7NzMv+WUQD/kUsA/5tXAP+dWQDy////AP///wD///8A////ANKaZP/SmmT/0ppk/9KaZP/Sm2X/z5NZ/8yMT//z5NX/////////////////////////////////////////////////////////////////9Ofa/8yNUP/UmGH/36p5/8yTWv+qaSD/kksA/5ROAPz///8A////AP///wD///8A0ppk5NKaZP/SmmT/0ppk/9KaZP/TnGf/zY9T/82OUv/t1sD//////////////////////////////////////////////////////+7Yw//OkFX/zI5R/9OcZ//SmmP/26V0/9ymdf/BhUf/ol8R6P///wD///8A////AP///wDSmmQ80ppk9tKaZP/SmmT/0ppk/9KaZP/TnGj/zpFW/8qJSv/dson/8uHS//////////////////////////////////Lj0//etIv/y4lL/86QVf/TnGj/0ppk/9KaZP/RmWP/05xn/9ymdfjUnWdC////AP///wD///8A////ANKaZADSmmQc0ppkotKaZP/SmmT/0ppk/9KaZP/Tm2b/0Zli/8qJSf/NjlH/16Z3/+G8mP/myKr/5siq/+G8mP/Xp3f/zY5S/8qISf/RmGH/05tm/9KaZP/SmmT/0ppk/9KaZP/SmmSm0pljINWdaQD///8A////AP///wD///8A0ppkANKaZADSmmQA0ppkQtKaZMrSmmT/0ppk/9KaZP/SmmT/0ptl/9GYYf/Nj1P/y4lL/8qISP/KiEj/y4lK/82PU//RmGH/0ptl/9KaZP/SmmT/0ppk/9KaZP/SmmTO0ppkRtKaZADSmmQA0ppkAP///wD///8A////AP///wDSmmQA0ppkANKaZADSmmQA0ppkANKaZGzSmmTu0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmTw0ppkcNKaZADSmmQA0ppkANKaZADSmmQA////AP///wD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZBLSmmSQ0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppklNKaZBTSmmQA0ppkANKaZADSmmQA0ppkANKaZAD///8A////AP///wD///8A0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQy0ppkutKaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppkvtKaZDbSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkAP///wD///8A////AP///wDSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkXNKaZODSmmT/0ppk/9KaZP/SmmT/0ppk5NKaZGDSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA////AP///wD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkBtKaZIbSmmTo0ppk6tKaZIrSmmQK0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZAD///8A////AP/8P///+B///+AH//+AAf//AAD//AAAP/AAAA/gAAAHwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA+AAAAfwAAAP/AAAP/8AAP//gAH//+AH///4H////D//" rel="icon" />
  
  <!--[if lt IE 9]>
    <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
  <![endif]-->
</head>
<body>
<div class="wrapper">
<header id="title-block-header">
<h1 class="title" style="text-align:center">Deducing function parameter
types using alias template CTAD</h1>
<table style="border:none;float:right">
  <tr>
    <td>Document #:</td>
    <td>P2998R0</td>
  </tr>
  <tr>
    <td>Date:</td>
    <td>2024-10-15</td>
  </tr>
  <tr>
    <td style="vertical-align:top">Project:</td>
    <td>Programming Language C++</td>
  </tr>
  <tr>
    <td style="vertical-align:top">Audience:</td>
    <td>
      Evolution<br>
    </td>
  </tr>
  <tr>
    <td style="vertical-align:top">Reply-to:</td>
    <td>
      James Touton<br>&lt;<a href="mailto:bekenn@gmail.com" class="email">bekenn@gmail.com</a>&gt;<br>
    </td>
  </tr>
</table>
</header>
<div style="clear:both">
<div id="TOC" role="doc-toc">
<h2 id="toctitle">Contents</h2>
<ul>
<li><a href="#introduction" id="toc-introduction"><span class="toc-section-number">1</span> Introduction<span></span></a></li>
<li><a href="#motivation" id="toc-motivation"><span class="toc-section-number">2</span> Motivation<span></span></a></li>
<li><a href="#design" id="toc-design"><span class="toc-section-number">3</span> Design<span></span></a>
<ul>
<li><a href="#general-approach-ctad-behind-the-scenes" id="toc-general-approach-ctad-behind-the-scenes"><span class="toc-section-number">3.1</span> General approach: CTAD behind the
scenes<span></span></a></li>
<li><a href="#limitations-of-deduction-guides" id="toc-limitations-of-deduction-guides"><span class="toc-section-number">3.2</span> Limitations of deduction
guides<span></span></a>
<ul>
<li><a href="#declaring-deduction-guides-for-alias-templates" id="toc-declaring-deduction-guides-for-alias-templates"><span class="toc-section-number">3.2.1</span> Declaring deduction guides for
alias templates<span></span></a></li>
<li><a href="#alternative-multiple-return-types-for-deduction-guides" id="toc-alternative-multiple-return-types-for-deduction-guides"><span class="toc-section-number">3.2.2</span> Alternative: Multiple return
types for deduction guides<span></span></a></li>
</ul></li>
<li><a href="#overload-resolution" id="toc-overload-resolution"><span class="toc-section-number">3.3</span> Overload
resolution<span></span></a></li>
</ul></li>
<li><a href="#wording" id="toc-wording"><span class="toc-section-number">4</span> Wording<span></span></a></li>
<li><a href="#acknowledgments" id="toc-acknowledgments"><span class="toc-section-number">5</span>
Acknowledgments<span></span></a></li>
<li><a href="#bibliography" id="toc-bibliography"><span class="toc-section-number">6</span> References<span></span></a></li>
</ul>
</div>
<h2 data-number="1" id="introduction"><span class="header-section-number">1</span> Introduction<a href="#introduction" class="self-link"></a></h2>
<p>This paper proposes to extend template argument deduction from a
function call to include candidates determined via class template
argument deduction when the type of a function parameter cannot
otherwise be deduced. This will allow some function templates to match a
much wider range of invocations involving conversions to the deduced
type rather than requiring an exact match. The feature works by
leveraging existing wording involving class template argument deduction
for alias templates, treating a dependent <em>template-id</em> as the
aliased type of a hypothetical alias template definition. Template
arguments for the hypothetical alias template are deduced using the
existing rules for class template argument deduction, and the results
are substituted back into the <em>template-id</em> of the function
parameter type. Template argument deduction for the function template
then proceeds as usual from the substituted parameter type.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&lt;span&gt;</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&lt;vector&gt;</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span> <span class="dt">void</span> f<span class="op">(</span>std<span class="op">::</span>span<span class="op">&lt;</span>T<span class="op">&gt;)</span>;</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span> <span class="dt">void</span> g<span class="op">(</span><span class="kw">const</span> std<span class="op">::</span>vector<span class="op">&lt;</span>T<span class="op">&gt;&amp;)</span>;</span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> example<span class="op">()</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> x<span class="op">[]</span> <span class="op">=</span> <span class="op">{</span> <span class="dv">1</span>, <span class="dv">2</span>, <span class="dv">3</span>, <span class="dv">4</span>, <span class="dv">5</span> <span class="op">}</span>;</span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a>    f<span class="op">(</span>x<span class="op">)</span>; <span class="co">// previously ill-formed, now OK; <span class="tcode">T</span> deduced as <span class="tcode">int</span></span></span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a>    g<span class="op">({</span> <span class="dv">1</span>, <span class="dv">2</span>, <span class="dv">3</span>, <span class="dv">4</span>, <span class="dv">5</span> <span class="op">})</span>; <span class="co">// previously ill-formed, now OK; <span class="tcode">T</span> deduced as <span class="tcode">int</span></span></span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>This paper also proposes to allow users to declare deduction guides
for alias templates.</p>
<h2 data-number="2" id="motivation"><span class="header-section-number">2</span> Motivation<a href="#motivation" class="self-link"></a></h2>
<p>Function templates are intended to behave very much like ordinary
functions in that they can be called like ordinary functions and
participate in overload resolution with ordinary functions. One way to
think of this is that a function template behaves as a collection of
overloads consisting of all possible substitutions of its template
parameters. At the point of a function call, the implementation compares
the list of function arguments against each available overload and
selects the overload that most closely matches the function arguments.
If the overload originated as a function template, then the template is
instantiated using the substitutions that generated the overload.</p>
<p>Of course, that’s not how it actually works. The set of substitutions
for a template is effectively unbounded; the implementation cannot
simply generate a list of all possible substitutions for a template.
Instead, the implementation follows a set of rules intended to determine
the most appropriate substitution for a template based on the
information available in the call and in the structure of the template
declaration. This keeps the search space manageable and, importantly,
avoids incidental instantiations of other participating templates.</p>
<p>The existing rules are generally very good and have withstood the
test of time; function templates are one of the most important bedrock
features in the language today, and have been since their inception. The
success of the language very much rests on the success of function
templates. However, there are limitations to the existing rules for
template argument deduction that exclude some desirable use cases.</p>
<p>For the most part, template argument deduction is limited to finding
a more-or-less exact match for the type of an argument expression.
Conversions are generally not considered. This is usually fine; if,
given a type template parameter
<code class="sourceCode default">T</code>, a function parameter’s type
is simply <code class="sourceCode default">T</code> (or some other
simple modification, such as
<code class="sourceCode default">const T&amp;</code>), then it doesn’t
make sense to consider substitutions other than the type of the function
argument, because any such substitution will be a worse match.
Similarly, if a function parameter’s type is some variation on
<code class="sourceCode default">vector&lt;T&gt;</code> and the argument
is a specialization of <code class="sourceCode default">vector</code>,
then it is easy (and correct) to say that the substitution for
<code class="sourceCode default">T</code> is the substitution that makes
<code class="sourceCode default">vector&lt;T&gt;</code> equal to the
argument type.</p>
<p>But there are cases where conversions may be desired, and the rules
don’t currently provide a way to handle that:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&lt;span&gt;</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&lt;vector&gt;</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span> <span class="dt">void</span> f<span class="op">(</span><span class="kw">const</span> T<span class="op">&amp;)</span>;</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span> <span class="dt">void</span> g<span class="op">(</span><span class="kw">const</span> std<span class="op">::</span>vector<span class="op">&lt;</span>T<span class="op">&gt;&amp;)</span>;</span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span> <span class="dt">void</span> h<span class="op">(</span>std<span class="op">::</span>span<span class="op">&lt;</span>T<span class="op">&gt;)</span>;</span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> example<span class="op">()</span></span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a>    std<span class="op">::</span>vector<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;</span> v;</span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true" tabindex="-1"></a>    f<span class="op">(</span>v<span class="op">)</span>; <span class="co">// OK, <span class="tcode">T</span> deduced as <span class="tcode">std::vector&lt;int&gt;</span></span></span>
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true" tabindex="-1"></a>    g<span class="op">(</span>v<span class="op">)</span>; <span class="co">// OK, <span class="tcode">T</span> deduced as <span class="tcode">int</span></span></span>
<span id="cb2-14"><a href="#cb2-14" aria-hidden="true" tabindex="-1"></a>    h<span class="op">(</span>v<span class="op">)</span>; <span class="co">// error: unable to deduce <span class="tcode">T</span></span></span>
<span id="cb2-15"><a href="#cb2-15" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>In the above example, based on our knowledge of
<code class="sourceCode default">std::span</code>, it is easy to see
that a match for the call to <code class="sourceCode default">h</code>
is possible; if <code class="sourceCode default">T</code> were to
somehow be deduced as <code class="sourceCode default">int</code>, then
the call to <code class="sourceCode default">h</code> would be valid.
And, in fact, there is an existing context in the language where that
deduction succeeds:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&lt;span&gt;</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&lt;vector&gt;</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>std<span class="op">::</span>vector<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;</span> v;</span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>std<span class="op">::</span>span s <span class="op">=</span> v; <span class="co">// OK, <span class="tcode">s</span> is <span class="tcode">std::span&lt;int, std::dynamic_extent&gt;</span></span></span></code></pre></div>
<p>By applying this mechanism in the context of a function call, we can
reproduce the successful deduction, and thereby make the language more
useful and more self-consistent.</p>
<h2 data-number="3" id="design"><span class="header-section-number">3</span> Design<a href="#design" class="self-link"></a></h2>
<h3 data-number="3.1" id="general-approach-ctad-behind-the-scenes"><span class="header-section-number">3.1</span> General approach: CTAD behind
the scenes<a href="#general-approach-ctad-behind-the-scenes" class="self-link"></a></h3>
<p>The mechanism is class template argument deduction (CTAD, <span class="citation" data-cites="P0091R3">[<a href="#ref-P0091R3" role="doc-biblioref">P0091R3</a>]</span>), initially introduced in C++17
with support for class templates, and later expanded in C++20 with
support for alias templates (<span class="citation" data-cites="P1814R0">[<a href="#ref-P1814R0" role="doc-biblioref">P1814R0</a>]</span>). With CTAD, an unspecialized
template name is used in a declaration as a placeholder for a
specialization of that template, which is inferred from the
declaration’s initializer. A placeholder may appear in variable
declarations, <code class="sourceCode default">new</code> expressions,
function-style casts, and non-type template parameter declarations, but
not in function parameter declarations.</p>
<p>Note that this paper <em>does not</em> propose allowing placeholders
in function parameter declarations:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> f<span class="op">(</span>std<span class="op">::</span>pair p<span class="op">)</span>; <span class="co">// NOT proposed</span></span></code></pre></div>
<p>Such a feature is certainly achievable, and may be useful in its own
right, but this approach has limitations because the placeholder syntax
disallows template arguments on the placeholder:</p>
<ul>
<li><p>It is impossible to express relationships between function
parameters making use of the same template parameters from the function
template. For instance, given the hypothetical declaration</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> copy<span class="op">(</span>std<span class="op">::</span>span from, std<span class="op">::</span>span to<span class="op">)</span>;</span></code></pre></div>
<p>there is no straightforward way to establish that the value types of
<code class="sourceCode default">from</code> and
<code class="sourceCode default">to</code> are the same, or that the
element type of <code class="sourceCode default">from</code> is
<code class="sourceCode default">const</code>-qualified while the
element type of <code class="sourceCode default">to</code> is
not.</p></li>
<li><p>CTAD using placeholders deduces arguments for <em>all</em>
parameters of the template; there is no way to provide explicit
arguments for some template parameters and deduce the others. Given a
declaration</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> V<span class="op">&gt;</span> <span class="dt">void</span> f<span class="op">(</span>std<span class="op">::</span>tuple<span class="op">&lt;</span>std<span class="op">::</span>string_view, V<span class="op">&gt;)</span>;</span></code></pre></div>
<p>we would like to be able to deduce
<code class="sourceCode default">V</code> given an argument of type
<code class="sourceCode default">std::pair&lt;std::string, int&gt;</code>.</p></li>
</ul>
<p>Given these shortcomings and a desire for the feature to work with
existing templates, the proposal is to make no changes to the existing
syntax for function parameters. Instead, the approach is to generate an
alias template from the function parameter type, and then perform
template argument deduction for the initialization of a variable
declared with the name of the alias template as its type and the
function argument as its initializer.</p>
<p>For example, given the function declaration and call argument from
the second bullet point above:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> V<span class="op">&gt;</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> f<span class="op">(</span>std<span class="op">::</span>tuple<span class="op">&lt;</span>std<span class="op">::</span>string_view, V<span class="op">&gt;)</span>;</span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> example<span class="op">()</span></span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a>    std<span class="op">::</span>pair<span class="op">&lt;</span>std<span class="op">::</span>string, <span class="dt">int</span><span class="op">&gt;</span> p <span class="op">=</span> <span class="op">{</span> <span class="st">&quot;hello&quot;</span>, <span class="dv">5</span> <span class="op">}</span>;</span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a>    f<span class="op">(</span>p<span class="op">)</span>;</span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>…an alias template and corresponding variable declaration are
considered. Template arguments for the type of the variable are
determined according to the rules for CTAD for alias templates (<span class="citation" data-cites="P1814R0">[<a href="#ref-P1814R0" role="doc-biblioref">P1814R0</a>]</span>):</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="co">// Hypothetical alias template</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> V<span class="op">&gt;</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a><span class="kw">using</span> A <span class="op">=</span> std<span class="op">::</span>tuple<span class="op">&lt;</span>std<span class="op">::</span>string_view, V<span class="op">&gt;</span>;</span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>A x <span class="op">=</span> p; <span class="co">// <span class="tcode">A</span> deduced as <span class="tcode">A&lt;int&gt;</span> (i.e. <span class="tcode">std::tuple&lt;std::string_view, int&gt;</span>)</span></span></code></pre></div>
<p>and the result is substituted back into the type of the function
parameter:</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a>f<span class="op">(</span>p<span class="op">)</span>; <span class="co">// OK, <span class="tcode">V</span> deduced as <span class="tcode">int</span></span></span></code></pre></div>
<h3 data-number="3.2" id="limitations-of-deduction-guides"><span class="header-section-number">3.2</span> Limitations of deduction
guides<a href="#limitations-of-deduction-guides" class="self-link"></a></h3>
<p>Consider this simple function template for copying data between two
contiguous ranges:</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> copy<span class="op">(</span>std<span class="op">::</span>span<span class="op">&lt;</span><span class="kw">const</span> T<span class="op">&gt;</span> from, std<span class="op">::</span>span<span class="op">&lt;</span>T<span class="op">&gt;</span> to<span class="op">)</span>;</span></code></pre></div>
<p>With the approach outlined above, this function template is now
directly callable using <code class="sourceCode default">span</code>s,
<code class="sourceCode default">vector</code>s, arrays (both built-in
and <code class="sourceCode default">std::</code>), or even braced
pointer/size pairs. (Of course, a more generic range concept could also
have handled all of those cases and more, but this approach has the
advantage of generating fewer template instantiations; everything
converts to some flavor of <code class="sourceCode default">span</code>
before the function call.) All of that would have required additional
overloads without this feature.</p>
<p>But there’s still a surprising gap in functionality here:</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> example<span class="op">(</span>std<span class="op">::</span>span<span class="op">&lt;</span><span class="kw">const</span> <span class="dt">int</span><span class="op">&gt;</span> src1, std<span class="op">::</span>span<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;</span> src2<span class="op">)</span></span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> dst<span class="op">[</span><span class="dv">5</span><span class="op">]</span>;</span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a>    copy<span class="op">(</span>src1, dst<span class="op">)</span>; <span class="co">// OK</span></span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a>    copy<span class="op">(</span>src2, dst<span class="op">)</span>; <span class="co">// error: deduction failed for <span class="tcode">T</span> from <span class="tcode">src2</span></span></span>
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>This stems from an existing limitation with deduction guides; the
same problem arises in existing code today:</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&lt;span&gt;</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> ElementType, std<span class="op">::</span><span class="dt">size_t</span> Extent <span class="op">=</span> std<span class="op">::</span>dynamic_extent<span class="op">&gt;</span></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a><span class="kw">using</span> const_span <span class="op">=</span> std<span class="op">::</span>span<span class="op">&lt;</span><span class="kw">const</span> ElementType, Extent<span class="op">&gt;</span>;</span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a>std<span class="op">::</span>span<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;</span> x;</span>
<span id="cb12-7"><a href="#cb12-7" aria-hidden="true" tabindex="-1"></a>const_span<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;</span> y <span class="op">=</span> x; <span class="co">// OK</span></span>
<span id="cb12-8"><a href="#cb12-8" aria-hidden="true" tabindex="-1"></a>const_span z <span class="op">=</span> x; <span class="co">// error: No guide for <span class="tcode">const_span</span> from <span class="tcode">std::span&lt;int, std::dynamic_extent&gt;</span></span></span></code></pre></div>
<p>To understand why this fails, we have to examine the set of guides
that are generated for
<code class="sourceCode default">const_span</code>. The guides for
<code class="sourceCode default">const_span</code> are generated from
the guides for <code class="sourceCode default">std::span</code>, of
which there are two that could conceivably be relevant to this
situation:</p>
<div class="sourceCode" id="cb13"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="kw">namespace</span> std</span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a>    <span class="co">// Guide generated from the copy constructor of <span class="tcode">std::span</span></span></span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> ElementType, <span class="dt">size_t</span> Extent<span class="op">&gt;</span></span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a>      span<span class="op">(</span><span class="kw">const</span> span<span class="op">&lt;</span>ElementType, Extent<span class="op">&gt;&amp;)</span> <span class="op">-&gt;</span> span<span class="op">&lt;</span>ElementType, Extent<span class="op">&gt;</span>;</span>
<span id="cb13-6"><a href="#cb13-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-7"><a href="#cb13-7" aria-hidden="true" tabindex="-1"></a>    <span class="co">// User-declared deduction guide for adapting contiguous ranges</span></span>
<span id="cb13-8"><a href="#cb13-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span> <span class="op">&lt;</span>ranges<span class="op">::</span>contiguous_range R<span class="op">&gt;</span></span>
<span id="cb13-9"><a href="#cb13-9" aria-hidden="true" tabindex="-1"></a>      span<span class="op">(</span>R<span class="op">&amp;&amp;)</span> <span class="op">-&gt;</span> span<span class="op">&lt;</span>remove_reference_t<span class="op">&lt;</span>ranges<span class="op">::</span>range_reference_t<span class="op">&lt;</span>R<span class="op">&gt;&gt;&gt;</span>;</span>
<span id="cb13-10"><a href="#cb13-10" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>These are the corresponding guides generated for
<code class="sourceCode default">const_span</code>:</p>
<div class="sourceCode" id="cb14"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> ElementType, std<span class="op">::</span><span class="dt">size_t</span> Extent<span class="op">&gt;</span></span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>  const_span<span class="op">(</span><span class="kw">const</span> std<span class="op">::</span>span<span class="op">&lt;</span><span class="kw">const</span> ElementType, Extent<span class="op">&gt;&amp;)</span> <span class="op">-&gt;</span> std<span class="op">::</span>span<span class="op">&lt;</span><span class="kw">const</span> ElementType, Extent<span class="op">&gt;</span></span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">requires</span> <em>deduces-const-span</em><span class="op">&lt;</span>std<span class="op">::</span>span<span class="op">&lt;</span><span class="kw">const</span> ElementType, Extent<span class="op">&gt;&gt;</span>;</span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span>std<span class="op">::</span>ranges<span class="op">::</span>contiguous_range R<span class="op">&gt;</span></span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a>  const_span<span class="op">(</span>R<span class="op">&amp;&amp;)</span> <span class="op">-&gt;</span> std<span class="op">::</span>span<span class="op">&lt;</span>std<span class="op">::</span>remove_reference_t<span class="op">&lt;</span>std<span class="op">::</span>ranges<span class="op">::</span>range_reference_t<span class="op">&lt;</span>R<span class="op">&gt;&gt;&gt;</span></span>
<span id="cb14-7"><a href="#cb14-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">requires</span> <em>deduces-const-span</em><span class="op">&lt;</span>std<span class="op">::</span>span<span class="op">&lt;</span>std<span class="op">::</span>remove_reference_t<span class="op">&lt;</span>std<span class="op">::</span>ranges<span class="op">::</span>range_reference_t<span class="op">&lt;</span>R<span class="op">&gt;&gt;&gt;&gt;</span>;</span></code></pre></div>
<p>Here, <em>deduces-const-span</em> is a constraint that is satisfied
if and only if template arguments for
<code class="sourceCode default">const_span</code> are deducible from
the type argument. This validates that, for a given set of template
arguments, the return type of the guide can be expressed as a
specialization of
<code class="sourceCode default">const_span</code>.</p>
<p>The first guide fails because it’s expecting a span of
<code class="sourceCode default">const ElementType</code>, while
<code class="sourceCode default">x</code> is a span of
(non-<code class="sourceCode default">const</code>)
<code class="sourceCode default">int</code>.</p>
<p>The second guide fails because the return type fails the deducibility
constraint. Substituting the type of
<code class="sourceCode default">x</code> for
<code class="sourceCode default">R</code>, we get:</p>
<div class="sourceCode" id="cb15"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a>const_span<span class="op">(</span>std<span class="op">::</span>span<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;&amp;)</span> <span class="op">-&gt;</span> std<span class="op">::</span>span<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;</span></span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">requires</span> <em>deduces-const-span</em><span class="op">&lt;</span>std<span class="op">::</span>span<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;&gt;</span>;</span></code></pre></div>
<p>where <code class="sourceCode default">std::span&lt;int&gt;</code>
cannot be expressed as a specialization of
<code class="sourceCode default">const_span</code>.</p>
<h4 data-number="3.2.1" id="declaring-deduction-guides-for-alias-templates"><span class="header-section-number">3.2.1</span> Declaring deduction guides
for alias templates<a href="#declaring-deduction-guides-for-alias-templates" class="self-link"></a></h4>
<p>We could solve this by providing our own user-declared guides for
<code class="sourceCode default">const_span</code>:</p>
<div class="sourceCode" id="cb16"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> ElementType, std<span class="op">::</span><span class="dt">size_t</span> Extent<span class="op">&gt;</span></span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a>  const_span<span class="op">(</span><span class="kw">const</span> std<span class="op">::</span>span<span class="op">&lt;</span>ElementType, Extent<span class="op">&gt;&amp;)</span> <span class="op">-&gt;</span> const_span<span class="op">&lt;</span>ElementType, Extent<span class="op">&gt;</span>;</span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a><span class="co">// etc</span></span></code></pre></div>
<p>…but the language does not currently allow us to do that. Users can
only declare deduction guides for class templates, not alias
templates.</p>
<p>This restriction is artificial. Language rules already require
implementations to keep track of a set of guides for each alias
template; allowing users to extend this set should pose no technical
challenge. (Indeed, with Clang, this change required only removing a
single check explicitly rejecting deduction guide declarations for alias
templates.)</p>
<p>With the addition of user-declared deduction guides, we can rewrite
the <code class="sourceCode default">copy</code> example in a form that
works:</p>
<div class="sourceCode" id="cb17"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&lt;span&gt;</span></span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> ElementType, std<span class="op">::</span><span class="dt">size_t</span> Extent <span class="op">=</span> std<span class="op">::</span>dynamic_extent<span class="op">&gt;</span></span>
<span id="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a><span class="kw">using</span> const_span <span class="op">=</span> std<span class="op">::</span>span<span class="op">&lt;</span><span class="kw">const</span> ElementType, Extent<span class="op">&gt;</span>;</span>
<span id="cb17-5"><a href="#cb17-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-6"><a href="#cb17-6" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> ElementType, std<span class="op">::</span><span class="dt">size_t</span> Extent<span class="op">&gt;</span></span>
<span id="cb17-7"><a href="#cb17-7" aria-hidden="true" tabindex="-1"></a>  const_span<span class="op">(</span><span class="kw">const</span> std<span class="op">::</span>span<span class="op">&lt;</span>ElementType, Extent<span class="op">&gt;&amp;)</span> <span class="op">-&gt;</span> const_span<span class="op">&lt;</span>ElementType, Extent<span class="op">&gt;</span>;</span>
<span id="cb17-8"><a href="#cb17-8" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span>std<span class="op">::</span>ranges<span class="op">::</span>contiguous_range R<span class="op">&gt;</span></span>
<span id="cb17-9"><a href="#cb17-9" aria-hidden="true" tabindex="-1"></a>  const_span<span class="op">(</span>R<span class="op">&amp;&amp;)</span> <span class="op">-&gt;</span> const_span<span class="op">&lt;</span>std<span class="op">::</span>remove_reference_t<span class="op">&lt;</span>std<span class="op">::</span>ranges<span class="op">::</span>range_reference_t<span class="op">&lt;</span>R<span class="op">&gt;&gt;&gt;</span>;</span>
<span id="cb17-10"><a href="#cb17-10" aria-hidden="true" tabindex="-1"></a><span class="co">// etc</span></span>
<span id="cb17-11"><a href="#cb17-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-12"><a href="#cb17-12" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span></span>
<span id="cb17-13"><a href="#cb17-13" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> copy<span class="op">(</span>const_span<span class="op">&lt;</span>T<span class="op">&gt;</span> from, std<span class="op">::</span>span<span class="op">&lt;</span>T<span class="op">&gt;</span> to<span class="op">)</span>;</span>
<span id="cb17-14"><a href="#cb17-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-15"><a href="#cb17-15" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> example<span class="op">(</span>std<span class="op">::</span>span<span class="op">&lt;</span><span class="kw">const</span> <span class="dt">int</span><span class="op">&gt;</span> src1, std<span class="op">::</span>span<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;</span> src2<span class="op">)</span></span>
<span id="cb17-16"><a href="#cb17-16" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="cb17-17"><a href="#cb17-17" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> dst<span class="op">[</span><span class="dv">5</span><span class="op">]</span>;</span>
<span id="cb17-18"><a href="#cb17-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-19"><a href="#cb17-19" aria-hidden="true" tabindex="-1"></a>    copy<span class="op">(</span>src1, dst<span class="op">)</span>; <span class="co">// OK</span></span>
<span id="cb17-20"><a href="#cb17-20" aria-hidden="true" tabindex="-1"></a>    copy<span class="op">(</span>src2, dst<span class="op">)</span>; <span class="co">// OK</span></span>
<span id="cb17-21"><a href="#cb17-21" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<h4 data-number="3.2.2" id="alternative-multiple-return-types-for-deduction-guides"><span class="header-section-number">3.2.2</span> Alternative: Multiple return
types for deduction guides<a href="#alternative-multiple-return-types-for-deduction-guides" class="self-link"></a></h4>
<p>There is another way in which the
<code class="sourceCode default">copy</code> example might be made to
work without the need for a rewrite or a custom alias template with
accompanying user-declared guides. Fundamentally, the problem is that a
deduction guide can only map a given set of inputs to a single
specialization of the template. Extending deduction guides to allow a
list of return types would allow us to express deeper relationships
between types and permit the implementation to choose the most
appropriate alternative for a given context.</p>
<p>Continuing with the <code class="sourceCode default">span</code>
example, we could add this user-declared deduction guide to show that
spans of <code class="sourceCode default">T</code> are adaptable to
spans of <code class="sourceCode default">const T</code>:</p>
<div class="sourceCode" id="cb18"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="kw">namespace</span> std</span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> ElementType, <span class="dt">size_t</span> Extent<span class="op">&gt;</span></span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a>    span<span class="op">(</span><span class="kw">const</span> span<span class="op">&lt;</span>ElementType, Extent<span class="op">&gt;&amp;)</span></span>
<span id="cb18-5"><a href="#cb18-5" aria-hidden="true" tabindex="-1"></a>      <span class="op">-&gt;</span> span<span class="op">&lt;</span>ElementType, Extent<span class="op">&gt;</span>,</span>
<span id="cb18-6"><a href="#cb18-6" aria-hidden="true" tabindex="-1"></a>         span<span class="op">&lt;</span>ElementType, dynamic_extent<span class="op">&gt;</span>,</span>
<span id="cb18-7"><a href="#cb18-7" aria-hidden="true" tabindex="-1"></a>         span<span class="op">&lt;</span><span class="kw">const</span> ElementType, Extent<span class="op">&gt;</span></span>
<span id="cb18-8"><a href="#cb18-8" aria-hidden="true" tabindex="-1"></a>         span<span class="op">&lt;</span><span class="kw">const</span> ElementType, dynamic_extent<span class="op">&gt;</span>;</span>
<span id="cb18-9"><a href="#cb18-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Each return type is an alternative deduction, expressed in decreasing
order of preference. Variable declarations using the name of a class
template would be unaffected by this change; the first alternative would
always be chosen. These alternatives would come into play for alias
templates; the compiler would try each alternative in the order given,
and the first to pass the deducibility constraint would be selected.</p>
<p>That would make the
<code class="sourceCode default">const_span</code> example work without
the need for additional user-declared deduction guides:</p>
<div class="sourceCode" id="cb19"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&lt;span&gt;</span></span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> ElementType, std<span class="op">::</span><span class="dt">size_t</span> Extent <span class="op">=</span> std<span class="op">::</span>dynamic_extent<span class="op">&gt;</span></span>
<span id="cb19-4"><a href="#cb19-4" aria-hidden="true" tabindex="-1"></a><span class="kw">using</span> const_span <span class="op">=</span> std<span class="op">::</span>span<span class="op">&lt;</span><span class="kw">const</span> ElementType, Extent<span class="op">&gt;</span>;</span>
<span id="cb19-5"><a href="#cb19-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb19-6"><a href="#cb19-6" aria-hidden="true" tabindex="-1"></a><span class="co">// No new deduction guides here!</span></span>
<span id="cb19-7"><a href="#cb19-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb19-8"><a href="#cb19-8" aria-hidden="true" tabindex="-1"></a>std<span class="op">::</span>span<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;</span> x;</span>
<span id="cb19-9"><a href="#cb19-9" aria-hidden="true" tabindex="-1"></a>const_span<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;</span> y <span class="op">=</span> x; <span class="co">// OK</span></span>
<span id="cb19-10"><a href="#cb19-10" aria-hidden="true" tabindex="-1"></a>const_span z <span class="op">=</span> x; <span class="co">// OK, implementation selects <span class="tcode">std::span&lt;const int,
std::dynamic_extent&gt;</span></span></span></code></pre></div>
<p>This idea has not yet been fully examined and may be revisited in a
future revision of this paper.</p>
<h3 data-number="3.3" id="overload-resolution"><span class="header-section-number">3.3</span> Overload resolution<a href="#overload-resolution" class="self-link"></a></h3>
<p>This feature makes some overloads viable that were not viable before,
potentially expanding the set of viable functions for a given function
call. This has the potential to make ambiguous a function call that was
previously well-formed:</p>
<div class="sourceCode" id="cb20"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span></span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> X <span class="op">{}</span>;</span>
<span id="cb20-3"><a href="#cb20-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb20-4"><a href="#cb20-4" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span></span>
<span id="cb20-5"><a href="#cb20-5" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> Y</span>
<span id="cb20-6"><a href="#cb20-6" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="cb20-7"><a href="#cb20-7" aria-hidden="true" tabindex="-1"></a>    Y<span class="op">(</span>X<span class="op">&lt;</span>T<span class="op">&gt;)</span>;</span>
<span id="cb20-8"><a href="#cb20-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb20-9"><a href="#cb20-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb20-10"><a href="#cb20-10" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span></span>
<span id="cb20-11"><a href="#cb20-11" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> f<span class="op">(</span>X<span class="op">&lt;</span>T<span class="op">&gt;</span>, <span class="dt">float</span><span class="op">)</span>; <span class="co">// #1</span></span>
<span id="cb20-12"><a href="#cb20-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb20-13"><a href="#cb20-13" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span></span>
<span id="cb20-14"><a href="#cb20-14" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> f<span class="op">(</span>Y<span class="op">&lt;</span>T<span class="op">&gt;</span>, <span class="dt">int</span><span class="op">)</span>; <span class="co">// #2</span></span>
<span id="cb20-15"><a href="#cb20-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb20-16"><a href="#cb20-16" aria-hidden="true" tabindex="-1"></a>f<span class="op">(</span>X<span class="op">&lt;</span><span class="dt">short</span><span class="op">&gt;()</span>, <span class="dv">5</span><span class="op">)</span>; <span class="co">// OK before, ambiguous with this proposal</span></span></code></pre></div>
<p>Without this proposal, the call to
<code class="sourceCode default">f</code> selects #1; #2 is non-viable
because <code class="sourceCode default">T</code> cannot be deduced from
the call. With this proposal, the call is ambiguous; #2 is now viable
with <code class="sourceCode default">T</code> deduced as
<code class="sourceCode default">short</code>, but #1 is a better match
for the first argument, while #2 is a better match for the second
argument.</p>
<p>It is currently unknown how much code in the wild would be broken by
adopting this feature. To avoid breaks, we could introduce a rule that
makes #2 a worse match than #1 by virtue of its use of this feature.
Such a rule would be decidedly unprincipled, and may lead to some
surprising results; arguably the call to
<code class="sourceCode default">f</code> <em>should</em> be ambiguous.
Still, even with the compatibility work-around, the feature should prove
useful.</p>
<h2 data-number="4" id="wording"><span class="header-section-number">4</span> Wording<a href="#wording" class="self-link"></a></h2>
<p>All changes are presented relative to <span class="citation" data-cites="N4986">[<a href="#ref-N4986" role="doc-biblioref">N4986</a>]</span>.</p>
<p>Modify §<span>12.2.2.9
<a href="https://wg21.link/over.match.class.deduct">[over.match.class.deduct]</a></span>
paragraph 1:</p>
<div class="std">
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span>
When resolving a placeholder for a deduced class type (<span>9.2.9.8
<a href="https://wg21.link/dcl.type.class.deduct">[dcl.type.class.deduct]</a></span>)
where the <em>template-name</em> names a primary class template
<code class="sourceCode default">C</code>, a set of functions and
function templates, called the guides of
<code class="sourceCode default">C</code>, is formed comprising:</p>
<ul>
<li><p><em>[…]</em></p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(1.4)</a></span> For
each <em>deduction-guide</em> <span class="add" style="color: #006e28"><ins>declared for
<span><code class="sourceCode default">C</code></span> (<span>13.7.2.3
<a href="https://wg21.link/temp.deduct.guide">[temp.deduct.guide]</a></span>)</ins></span>,
a function or function template <span class="rm" style="color: #bf0303"><del>with the following properties:</del></span>
<span class="add" style="color: #006e28"><ins>as described
below.</ins></span></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(1.4.1)</a></span>
<span class="rm" style="color: #bf0303"><del>The <em>template-head</em>,
if any, and <em>parameter-declaration-clause</em> are those of the
<em>deduction-guide</em>.</del></span></p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(1.4.2)</a></span>
<span class="rm" style="color: #bf0303"><del>The return type is the
<em>simple-template-id</em> of the
<em>deduction-guide</em>.</del></span></p></li>
</ul></li>
</ul>
<p><em>[…]</em></p>
</blockquote>
</div>
<p>Modify §<span>12.2.2.9
<a href="https://wg21.link/over.match.class.deduct">[over.match.class.deduct]</a></span>
paragraph 3:</p>
<div class="std">
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span>
When resolving a placeholder for a deduced class type (<span>9.2.9.3
<a href="https://wg21.link/dcl.type.simple">[dcl.type.simple]</a></span>)
where the <em>template-name</em> names an alias template
<code class="sourceCode default">A</code>, the <em>defining-type-id</em>
of <code class="sourceCode default">A</code> must be of the form</p>
<div class="line-block">       <code class="sourceCode default">typename</code><sub><em>opt</em></sub>
<em>nested-name-specifier</em><sub><em>opt</em></sub>
<code class="sourceCode default">template</code><sub><em>opt</em></sub>
<em>simple-template-id</em></div>
<p>as specified in <span>9.2.9.3
<a href="https://wg21.link/dcl.type.simple">[dcl.type.simple]</a></span>.
<span class="add" style="color: #006e28"><ins>Let
<span><code class="sourceCode default">B</code></span> be the template
named by the <em>simple-template-id</em> of the
<em>defining-type-id</em> of
<span><code class="sourceCode default">A</code></span>.</ins></span> The
guides of <code class="sourceCode default">A</code> are the set of
functions or function templates <span class="rm" style="color: #bf0303"><del>formed as follows.</del></span> <span class="add" style="color: #006e28"><ins>comprising:</ins></span></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(3.1)</a></span> For
each function or function template
<code class="sourceCode default">f</code> in the guides of <span class="rm" style="color: #bf0303"><del>the template named by the
<em>simple-template-id</em> of the
<em>defining-type-id</em></del></span> <span class="add" style="color: #006e28"><ins><span><code class="sourceCode default">B</code></span></ins></span>,
<span class="add" style="color: #006e28"><ins>a corresponding function
or function template
<span><code class="sourceCode default">f</code></span>′ formed as
follows:</ins></span> <span class="rm" style="color: #bf0303"><del>the
template</del></span> <span class="add" style="color: #006e28"><ins>Template</ins></span> arguments <span class="rm" style="color: #bf0303"><del>of</del></span> <span class="add" style="color: #006e28"><ins>for the template parameters used
in</ins></span> the return type of
<code class="sourceCode default">f</code> are deduced from the
<em>defining-type-id</em> of <code class="sourceCode default">A</code>
according to the process in <span>13.10.3.6
<a href="https://wg21.link/temp.deduct.type">[temp.deduct.type]</a></span>
with the exception that deduction does not fail if not all template
arguments are deduced. If deduction fails for another reason, proceed
with an empty set of deduced template arguments. Let
<code class="sourceCode default">g</code> denote the result of
substituting these deductions into
<code class="sourceCode default">f</code>. If substitution <span class="rm" style="color: #bf0303"><del>succeeds</del></span> <span class="add" style="color: #006e28"><ins>fails, there is no
<span><code class="sourceCode default">f</code></span>′ corresponding to
this <span><code class="sourceCode default">f</code></span>;
otherwise</ins></span>, <span class="rm" style="color: #bf0303"><del>form a function or function
template</del></span> <code class="sourceCode default">f</code>′ <span class="rm" style="color: #bf0303"><del>with</del></span> <span class="add" style="color: #006e28"><ins>has</ins></span> the following
properties <span class="rm" style="color: #bf0303"><del>and add it to
the set of guides of
<span><code class="sourceCode default">A</code></span></del></span>:</p>
<ul>
<li><em>[…]</em></li>
</ul></li>
</ul>
<div class="ins">
<ul>
<li><span class="marginalizedparent"><a class="marginalized">(3.2)</a></span> For
each <em>deduction-guide</em> declared for
<code class="sourceCode default">A</code> (<span>13.7.2.3
<a href="https://wg21.link/temp.deduct.guide">[temp.deduct.guide]</a></span>),
a function or function template as described below.</li>
</ul>
<p>If a function or function template in the guides of
<code class="sourceCode default">A</code> formed from the guides of
<code class="sourceCode default">B</code> would potentially
conflict (<span>6.4.1
<a href="https://wg21.link/basic.scope.scope">[basic.scope.scope]</a></span>)
with a function or function template formed from a
<em>deduction-guide</em> declared for A if given the same name, then the
former is discarded.</p>
</div>
</blockquote>
</div>
<p>Insert a new paragraph immediately following the above modified
paragraph:</p>
<div class="std ins">
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">4</a></span>
A guide formed from a <em>deduction-guide</em> has the following
properties:</p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">(.1)</a></span> The
<em>template-head</em>, if any, and
<em>parameter-declaration-clause</em> are those of the
<em>deduction-guide</em>.</li>
<li><span class="marginalizedparent"><a class="marginalized">(.2)</a></span> The
return type is the <em>simple-template-id</em> of the
<em>deduction-guide</em>.</li>
</ul>
</blockquote>
</div>
<p>Modify §<span>13.7.2.3
<a href="https://wg21.link/temp.deduct.guide">[temp.deduct.guide]</a></span>
paragraph 1:</p>
<div class="std">
<blockquote>
<div class="ins">
<div class="line-block">       <em>deduction-guide</em>:<br />
               <em>explicit-specifier</em><sub><em>opt</em></sub>
<em>template-name</em> <code class="sourceCode default">(</code>
<em>parameter-declaration-clause</em>
<code class="sourceCode default">)</code>
<em>requires-clause</em><sub><em>opt</em></sub>
<code class="sourceCode default">-&gt;</code>
<em>simple-template-id</em>
<code class="sourceCode default">;</code></div>
</div>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span>
Deduction guides are used when a <em>template-name</em> appears as a
type specifier for a deduced class type (<span>9.2.9.8
<a href="https://wg21.link/dcl.type.class.deduct">[dcl.type.class.deduct]</a></span>).
<span class="add" style="color: #006e28"><ins>A deduction guide is
<em>declared for</em> the template named by its
<em>template-name</em>.</ins></span> Deduction guides are not found by
name lookup. Instead, when performing class template argument
deduction (<span>12.2.2.9
<a href="https://wg21.link/over.match.class.deduct">[over.match.class.deduct]</a></span>),
all reachable deduction guides declared for the <span class="rm" style="color: #bf0303"><del>class</del></span> template are
considered.</p>
<div class="del">
<div class="line-block">       <em>deduction-guide</em>:<br />
               <em>explicit-specifier</em><sub><em>opt</em></sub>
<em>template-name</em> <code class="sourceCode default">(</code>
<em>parameter-declaration-clause</em>
<code class="sourceCode default">)</code>
<em>requires-clause</em><sub><em>opt</em></sub>
<code class="sourceCode default">-&gt;</code>
<em>simple-template-id</em>
<code class="sourceCode default">;</code></div>
</div>
</blockquote>
</div>
<p>Modify §<span>13.7.2.3
<a href="https://wg21.link/temp.deduct.guide">[temp.deduct.guide]</a></span>
paragraph 3:</p>
<div class="std">
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span>
The same restrictions apply to the <em>parameter-declaration-clause</em>
of a deduction guide as in a function declaration (<span>9.3.4.6
<a href="https://wg21.link/dcl.fct">[dcl.fct]</a></span>), except that a
generic parameter type placeholder (<span>9.2.9.7
<a href="https://wg21.link/dcl.spec.auto">[dcl.spec.auto]</a></span>)
shall not appear in the <em>parameter-declaration-clause</em> of a
deduction guide. The <span class="rm" style="color: #bf0303"><del><em>simple-template-id</em></del></span>
<span class="add" style="color: #006e28"><ins><em>template-name</em></ins></span> shall
name a <span class="rm" style="color: #bf0303"><del>class template
specialization</del></span> <span class="add" style="color: #006e28"><ins>deducible template (<span>9.2.9.3
<a href="https://wg21.link/dcl.type.simple">[dcl.type.simple]</a></span>)
and the <em>simple-template-id</em> shall name a specialization of that
template</ins></span>. The <em>template-name</em> shall be the same
<em>identifier</em> as the <em>template-name</em> of the
<em>simple-template-id</em>. A <em>deduction-guide</em> shall inhabit
the scope to which the corresponding <span class="rm" style="color: #bf0303"><del>class</del></span> template belongs and, for
a member <span class="rm" style="color: #bf0303"><del>class</del></span>
template, have the same access. Two deduction guide declarations for the
same <span class="rm" style="color: #bf0303"><del>class</del></span>
template shall not have equivalent
<em>parameter-declaration-clause</em>s if either is reachable from the
other.</p>
</blockquote>
</div>
<p>Split §<span>13.10.3.2
<a href="https://wg21.link/temp.deduct.call">[temp.deduct.call]</a></span>
paragraph 1 after the first sentence, with modifications as shown:</p>
<div class="std">
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span>
Template argument deduction is done by comparing each function template
parameter type <span class="rm" style="color: #bf0303"><del>(call
it</del></span> <code class="sourceCode default">P</code><span class="rm" style="color: #bf0303"><del>)</del></span> that contains
<em>template-parameter</em>s that participate in template argument
deduction with the type <span class="add" style="color: #006e28"><ins><span><code class="sourceCode default">A</code></span></ins></span>
of the corresponding argument of the call <span class="rm" style="color: #bf0303"><del>(call it
<span><code class="sourceCode default">A</code></span>)</del></span> as
described <span class="add" style="color: #006e28"><ins>in
<span>13.10.3.6
<a href="https://wg21.link/temp.deduct.type">[temp.deduct.type]</a></span></ins></span><span class="add" style="color: #006e28"><ins>, with potential modifications
to <span><code class="sourceCode default">P</code></span> and
<span><code class="sourceCode default">A</code></span> as
described</ins></span> below.</p>
</blockquote>
</div>
<p>Form a new paragraph from the remainder, with modifications as shown,
splitting it again after the first example:</p>
<div class="std">
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span>
If removing references and cv-qualifiers from
<code class="sourceCode default">P</code> gives
<code class="sourceCode default">std::initializer_list&lt;P</code>′<code class="sourceCode default">&gt;</code>
or
<code class="sourceCode default">P</code>′<code class="sourceCode default">[N]</code>
for some <code class="sourceCode default">P</code>′ and
<code class="sourceCode default">N</code> and the argument is a
non-empty initializer list (<span>9.4.5
<a href="https://wg21.link/dcl.init.list">[dcl.init.list]</a></span>),
then deduction is performed instead for each element of the initializer
list independently, taking <code class="sourceCode default">P</code>′ as
separate function template parameter types
<code class="sourceCode default">P</code>′<sub><em>i</em></sub> and the
<em>i</em><sup>th</sup> initializer element as the corresponding
argument. In the
<code class="sourceCode default">P</code>′<code class="sourceCode default">[N]</code>
case, if <code class="sourceCode default">N</code> is a non-type
template parameter, <code class="sourceCode default">N</code> is deduced
from the length of the initializer list. <span class="rm" style="color: #bf0303"><del>Otherwise, an initializer list argument
causes the parameter to be considered a non-deduced
context (<span>13.10.3.6
<a href="https://wg21.link/temp.deduct.type">[temp.deduct.type]</a></span>).</del></span></p>
<div class="example">
<span>[ <em>Example:</em> </span>
<div class="sourceCode" id="cb21"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-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> f<span class="op">(</span>std<span class="op">::</span>initializer_list<span class="op">&lt;</span>T<span class="op">&gt;)</span>;</span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a>f<span class="op">({</span><span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span><span class="op">})</span>;                     <span class="co">// <span class="tcode">T</span> deduced as <span class="tcode">int</span></span></span>
<span id="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a>f<span class="op">({</span><span class="dv">1</span>,<span class="st">&quot;asdf&quot;</span><span class="op">})</span>;                  <span class="co">// error: <span class="tcode">T</span> deduced as both <span class="tcode">int</span> and <span class="tcode">const char*</span></span></span>
<span id="cb21-4"><a href="#cb21-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb21-5"><a href="#cb21-5" aria-hidden="true" tabindex="-1"></a><span class="rm" style="color: #bf0303"><del>template&lt;class T&gt; void g(T);</del></span></span>
<span id="cb21-6"><a href="#cb21-6" aria-hidden="true" tabindex="-1"></a><span class="rm" style="color: #bf0303"><del>g({1,2,3});                     <span class="co">// error: no argument deduced for <span class="tcode">T</span></span></del></span></span>
<span id="cb21-7"><a href="#cb21-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb21-8"><a href="#cb21-8" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> T, <span class="dt">int</span> N<span class="op">&gt;</span> <span class="dt">void</span> h<span class="op">(</span>T <span class="kw">const</span><span class="op">(&amp;)[</span>N<span class="op">])</span>;</span>
<span id="cb21-9"><a href="#cb21-9" aria-hidden="true" tabindex="-1"></a>h<span class="op">({</span><span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span><span class="op">})</span>;                     <span class="co">// <span class="tcode">T</span> deduced as <span class="tcode">int</span>; <span class="tcode">N</span> deduced as <span class="tcode">3</span></span></span>
<span id="cb21-10"><a href="#cb21-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb21-11"><a href="#cb21-11" aria-hidden="true" tabindex="-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> j<span class="op">(</span>T <span class="kw">const</span><span class="op">(&amp;)[</span><span class="dv">3</span><span class="op">])</span>;</span>
<span id="cb21-12"><a href="#cb21-12" aria-hidden="true" tabindex="-1"></a>j<span class="op">({</span><span class="dv">42</span><span class="op">})</span>;                        <span class="co">// <span class="tcode">T</span> deduced as <span class="tcode">int</span>; array bound not considered</span></span>
<span id="cb21-13"><a href="#cb21-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb21-14"><a href="#cb21-14" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> Aggr <span class="op">{</span> <span class="dt">int</span> i; <span class="dt">int</span> j; <span class="op">}</span>;</span>
<span id="cb21-15"><a href="#cb21-15" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="dt">int</span> N<span class="op">&gt;</span> <span class="dt">void</span> k<span class="op">(</span>Aggr <span class="kw">const</span><span class="op">(&amp;)[</span>N<span class="op">])</span>;</span>
<span id="cb21-16"><a href="#cb21-16" aria-hidden="true" tabindex="-1"></a>k<span class="op">({</span><span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span><span class="op">})</span>;                     <span class="co">// error: deduction fails, no conversion from <span class="tcode">int</span> to <span class="tcode">Aggr</span></span></span>
<span id="cb21-17"><a href="#cb21-17" aria-hidden="true" tabindex="-1"></a>k<span class="op">({{</span><span class="dv">1</span><span class="op">}</span>,<span class="op">{</span><span class="dv">2</span><span class="op">}</span>,<span class="op">{</span><span class="dv">3</span><span class="op">}})</span>;               <span class="co">// OK, <span class="tcode">N</span> deduced as <span class="tcode">3</span></span></span>
<span id="cb21-18"><a href="#cb21-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb21-19"><a href="#cb21-19" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="dt">int</span> M, <span class="dt">int</span> N<span class="op">&gt;</span> <span class="dt">void</span> m<span class="op">(</span><span class="dt">int</span> <span class="kw">const</span><span class="op">(&amp;)[</span>M<span class="op">][</span>N<span class="op">])</span>;</span>
<span id="cb21-20"><a href="#cb21-20" aria-hidden="true" tabindex="-1"></a>m<span class="op">({{</span><span class="dv">1</span>,<span class="dv">2</span><span class="op">}</span>,<span class="op">{</span><span class="dv">3</span>,<span class="dv">4</span><span class="op">}})</span>;               <span class="co">// <span class="tcode">M</span> and <span class="tcode">N</span> both deduced as <span class="tcode">2</span></span></span>
<span id="cb21-21"><a href="#cb21-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb21-22"><a href="#cb21-22" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> T, <span class="dt">int</span> N<span class="op">&gt;</span> <span class="dt">void</span> n<span class="op">(</span>T <span class="kw">const</span><span class="op">(&amp;)[</span>N<span class="op">]</span>, T<span class="op">)</span>;</span>
<span id="cb21-23"><a href="#cb21-23" aria-hidden="true" tabindex="-1"></a>n<span class="op">({{</span><span class="dv">1</span><span class="op">}</span>,<span class="op">{</span><span class="dv">2</span><span class="op">}</span>,<span class="op">{</span><span class="dv">3</span><span class="op">}}</span>,Aggr<span class="op">())</span>;        <span class="co">// OK, <span class="tcode">T</span> is <span class="tcode">Aggr</span>, <span class="tcode">N</span> is <span class="tcode">3</span></span></span>
<span id="cb21-24"><a href="#cb21-24" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb21-25"><a href="#cb21-25" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">typename</span> T, <span class="dt">int</span> N<span class="op">&gt;</span> <span class="dt">void</span> o<span class="op">(</span>T <span class="op">(*</span> <span class="kw">const</span> <span class="op">(&amp;)[</span>N<span class="op">])(</span>T<span class="op">))</span> <span class="op">{</span> <span class="op">}</span></span>
<span id="cb21-26"><a href="#cb21-26" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> f1<span class="op">(</span><span class="dt">int</span><span class="op">)</span>;</span>
<span id="cb21-27"><a href="#cb21-27" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> f4<span class="op">(</span><span class="dt">int</span><span class="op">)</span>;</span>
<span id="cb21-28"><a href="#cb21-28" aria-hidden="true" tabindex="-1"></a><span class="dt">char</span> f4<span class="op">(</span><span class="dt">char</span><span class="op">)</span>;</span>
<span id="cb21-29"><a href="#cb21-29" aria-hidden="true" tabindex="-1"></a>o<span class="op">({</span> <span class="op">&amp;</span>f1, <span class="op">&amp;</span>f4 <span class="op">})</span>;                                <span class="co">// OK, <span class="tcode">T</span> deduced as <span class="tcode">int</span> from first element, nothing</span></span>
<span id="cb21-30"><a href="#cb21-30" aria-hidden="true" tabindex="-1"></a>                                                <span class="co">// deduced from second element, <span class="tcode">N</span> deduced as <span class="tcode">2</span></span></span>
<span id="cb21-31"><a href="#cb21-31" aria-hidden="true" tabindex="-1"></a>o<span class="op">({</span> <span class="op">&amp;</span>f1, <span class="kw">static_cast</span><span class="op">&lt;</span><span class="dt">char</span><span class="op">(*)(</span><span class="dt">char</span><span class="op">)&gt;(&amp;</span>f4<span class="op">)</span> <span class="op">})</span>;    <span class="co">// error: conflicting deductions for <span class="tcode">T</span></span></span></code></pre></div>
<span> — <em>end example</em> ]</span>
</div>
</blockquote>
</div>
<p>Insert a new paragraph immediately following the above modified
paragraph:</p>
<div class="std ins">
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span>
If removing references and cv-qualifiers from
<code class="sourceCode default">P</code> yields a specialization
<code class="sourceCode default">P</code>′ of a deducible
template (<span>9.2.9.3
<a href="https://wg21.link/dcl.type.simple">[dcl.type.simple]</a></span>)
other than
<code class="sourceCode default">std::initializer_list</code>, and
either</p>
<ul>
<li>the argument is an initializer list, or</li>
<li>the deducible template is a class template and
<code class="sourceCode default">A</code> is neither a specialization of
the same class template nor a class derived from such,</li>
</ul>
<p>deduction is performed as described in <span>12.2.2.9
<a href="https://wg21.link/over.match.class.deduct">[over.match.class.deduct]</a></span>
for a declaration of the form</p>
<div class="line-block">       <code class="sourceCode default">PA x = a;</code></div>
<p>where <code class="sourceCode default">PA</code> is the name of a
hypothetical alias template whose <em>defining-type-id</em> is
<code class="sourceCode default">P</code>′ and whose template parameter
list consists of all the template parameters of the enclosing function
template that appear in <code class="sourceCode default">P</code>′, and
<code class="sourceCode default">a</code> is the function argument
corresponding to <code class="sourceCode default">P</code>. If the
deduction succeeds, then the type of
<code class="sourceCode default">x</code> is used in place of
<code class="sourceCode default">A</code> for type deduction.</p>
<div class="example">
<span>[ <em>Example:</em> </span>
<div class="sourceCode" id="cb22"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> T<span class="op">&gt;</span> <span class="kw">struct</span> P <span class="op">{</span> P<span class="op">(</span>T<span class="op">*)</span>; <span class="op">}</span>;</span>
<span id="cb22-2"><a href="#cb22-2" aria-hidden="true" tabindex="-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> p<span class="op">(</span>P<span class="op">&lt;</span>T<span class="op">&gt;)</span>;</span>
<span id="cb22-3"><a href="#cb22-3" aria-hidden="true" tabindex="-1"></a><span class="dt">float</span> x;</span>
<span id="cb22-4"><a href="#cb22-4" aria-hidden="true" tabindex="-1"></a>p<span class="op">(&amp;</span>x<span class="op">)</span>;                          <span class="co">// OK, <span class="tcode">T</span> deduced as <span class="tcode">float</span></span></span>
<span id="cb22-5"><a href="#cb22-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb22-6"><a href="#cb22-6" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> T<span class="op">&gt;</span> <span class="kw">struct</span> V <span class="op">{</span> V<span class="op">(</span>std<span class="op">::</span>initializer_list<span class="op">&lt;</span>T<span class="op">&gt;)</span>; <span class="op">}</span>;</span>
<span id="cb22-7"><a href="#cb22-7" aria-hidden="true" tabindex="-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> q<span class="op">(</span>V<span class="op">&lt;</span>T<span class="op">&gt;)</span>;</span>
<span id="cb22-8"><a href="#cb22-8" aria-hidden="true" tabindex="-1"></a>q<span class="op">({</span> <span class="dv">1</span>, <span class="dv">2</span>, <span class="dv">3</span> <span class="op">})</span>;                 <span class="co">// OK, <span class="tcode">T</span> deduced as <span class="tcode">int</span></span></span>
<span id="cb22-9"><a href="#cb22-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb22-10"><a href="#cb22-10" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> T1, <span class="kw">class</span> T2<span class="op">&gt;</span> <span class="kw">struct</span> Pair <span class="op">{</span> T1 a; T2 b; <span class="op">}</span>;</span>
<span id="cb22-11"><a href="#cb22-11" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> T1, <span class="kw">class</span> T2<span class="op">&gt;</span> r<span class="op">(</span><span class="kw">const</span> Pair<span class="op">&lt;</span>T1, T2<span class="op">&gt;&amp;)</span>;</span>
<span id="cb22-12"><a href="#cb22-12" aria-hidden="true" tabindex="-1"></a>r<span class="op">({</span> <span class="st">&quot;pi&quot;</span>, <span class="fl">3.14159</span> <span class="op">})</span>;           <span class="co">// <span class="tcode">T1</span> deduced as <span class="tcode">const char*</span>; <span class="tcode">T2</span> deduced as <span class="tcode">double</span></span></span>
<span id="cb22-13"><a href="#cb22-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb22-14"><a href="#cb22-14" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> T, std<span class="op">::</span><span class="dt">size_t</span> N<span class="op">&gt;</span> <span class="kw">struct</span> A <span class="op">{</span> A<span class="op">(</span>T <span class="op">(&amp;)[</span>N<span class="op">])</span>; <span class="op">}</span>;</span>
<span id="cb22-15"><a href="#cb22-15" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span>std<span class="op">::</span><span class="dt">size_t</span> N<span class="op">&gt;</span> s<span class="op">(</span>A<span class="op">&lt;</span><span class="dt">int</span>, N<span class="op">&gt;&amp;&amp;)</span>;</span>
<span id="cb22-16"><a href="#cb22-16" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> arr<span class="op">[]</span> <span class="op">=</span> <span class="op">{</span> <span class="dv">1</span>, <span class="dv">2</span>, <span class="dv">3</span>, <span class="dv">4</span>, <span class="dv">5</span> <span class="op">}</span>;</span>
<span id="cb22-17"><a href="#cb22-17" aria-hidden="true" tabindex="-1"></a>s<span class="op">(</span>arr<span class="op">)</span>;                         <span class="co">// OK, <span class="tcode">N</span> deduced as <span class="tcode">5</span></span></span></code></pre></div>
<span> — <em>end example</em> ]</span>
</div>
</blockquote>
</div>
<p>Insert a new paragraph immediately following the above insterted
paragraph:</p>
<div class="std ins">
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">4</a></span>
In all other cases, an initializer list argument causes the parameter to
be considered a non-deduced context (<span>13.10.3.6
<a href="https://wg21.link/temp.deduct.type">[temp.deduct.type]</a></span>).</p>
<div class="example">
<span>[ <em>Example:</em> </span>
<div class="sourceCode" id="cb23"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-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> g<span class="op">(</span>T<span class="op">)</span>;</span>
<span id="cb23-2"><a href="#cb23-2" aria-hidden="true" tabindex="-1"></a>g<span class="op">({</span><span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span><span class="op">})</span>;                     <span class="co">// error: no argument deduced for <span class="tcode">T</span></span></span></code></pre></div>
<span> — <em>end example</em> ]</span>
</div>
</blockquote>
</div>
<p>Retain the remainder of the original paragraph 1 unchanged as a new
paragraph immediately following the above inserted paragraph:</p>
<div class="std">
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">5</a></span>
For a function parameter pack that occurs at the end of the
<em>parameter-declaration-list</em>, deduction is performed for each
remaining argument of the call, taking the type
<code class="sourceCode default">P</code> of the <em>declarator-id</em>
of the function parameter pack as the corresponding function template
parameter type. Each deduction deduces template arguments for subsequent
positions in the template parameter packs expanded by the function
parameter pack. When a function parameter pack appears in a non-deduced
context (<span>13.10.3.6
<a href="https://wg21.link/temp.deduct.type">[temp.deduct.type]</a></span>),
the type of that pack is never deduced.</p>
<div class="example">
<span>[ <em>Example:</em> </span>
<div class="sourceCode" id="cb24"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> <span class="op">...</span> Types<span class="op">&gt;</span> <span class="dt">void</span> f<span class="op">(</span>Types<span class="op">&amp;</span> <span class="op">...)</span>;</span>
<span id="cb24-2"><a href="#cb24-2" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> T1, <span class="kw">class</span> <span class="op">...</span> Types<span class="op">&gt;</span> <span class="dt">void</span> g<span class="op">(</span>T1, Types <span class="op">...)</span>;</span>
<span id="cb24-3"><a href="#cb24-3" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> T1, <span class="kw">class</span> <span class="op">...</span> Types<span class="op">&gt;</span> <span class="dt">void</span> g1<span class="op">(</span>Types <span class="op">...</span>, T1<span class="op">)</span>;</span>
<span id="cb24-4"><a href="#cb24-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb24-5"><a href="#cb24-5" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> h<span class="op">(</span><span class="dt">int</span> x, <span class="dt">float</span><span class="op">&amp;</span> y<span class="op">)</span> <span class="op">{</span></span>
<span id="cb24-6"><a href="#cb24-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> <span class="dt">int</span> z <span class="op">=</span> x;</span>
<span id="cb24-7"><a href="#cb24-7" aria-hidden="true" tabindex="-1"></a>  f<span class="op">(</span>x, y, z<span class="op">)</span>;                   <span class="co">// <span class="tcode">Types</span> deduced as <span class="tcode">int</span>, <span class="tcode">float</span>, <span class="tcode">const int</span></span></span>
<span id="cb24-8"><a href="#cb24-8" aria-hidden="true" tabindex="-1"></a>  g<span class="op">(</span>x, y, z<span class="op">)</span>;                   <span class="co">// <span class="tcode">T1</span> deduced as <span class="tcode">int</span>; <span class="tcode">Types</span> deduced as <span class="tcode">float</span>, <span class="tcode">int</span></span></span>
<span id="cb24-9"><a href="#cb24-9" aria-hidden="true" tabindex="-1"></a>  g1<span class="op">(</span>x, y, z<span class="op">)</span>;                  <span class="co">// error: <span class="tcode">Types</span> is not deduced</span></span>
<span id="cb24-10"><a href="#cb24-10" aria-hidden="true" tabindex="-1"></a>  g1<span class="op">&lt;</span><span class="dt">int</span>, <span class="dt">int</span>, <span class="dt">int</span><span class="op">&gt;(</span>x, y, z<span class="op">)</span>;   <span class="co">// OK, no deduction occurs</span></span>
<span id="cb24-11"><a href="#cb24-11" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<span> — <em>end example</em> ]</span>
</div>
</blockquote>
</div>
<h2 data-number="5" id="acknowledgments"><span class="header-section-number">5</span> Acknowledgments<a href="#acknowledgments" class="self-link"></a></h2>
<p>Thanks to Mike Spertus for some early feedback on the proposal.</p>
<h2 data-number="6" id="bibliography"><span class="header-section-number">6</span> References<a href="#bibliography" class="self-link"></a></h2>
<div id="refs" class="references csl-bib-body hanging-indent" role="doc-bibliography">
<div id="ref-N4986" class="csl-entry" role="doc-biblioentry">
[N4986] Thomas Köppe. 2024-07-16. Working Draft, Programming Languages —
C++. <a href="https://wg21.link/n4986"><div class="csl-block">https://wg21.link/n4986</div></a>
</div>
<div id="ref-P0091R3" class="csl-entry" role="doc-biblioentry">
[P0091R3] Mike Spertus, Faisal Vali, Richard Smith. 2016-06-24. Template
argument deduction for class templates (Rev. 6). <a href="https://wg21.link/p0091r3"><div class="csl-block">https://wg21.link/p0091r3</div></a>
</div>
<div id="ref-P1814R0" class="csl-entry" role="doc-biblioentry">
[P1814R0] Mike Spertus. 2019-07-28. Wording for Class Template Argument
Deduction for Alias Templates. <a href="https://wg21.link/p1814r0"><div class="csl-block">https://wg21.link/p1814r0</div></a>
</div>
</div>
</div>
</div>
</body>
</html>
