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

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

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

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

code.sourceCode > span { display: inline; }
</style>
  <style type="text/css">a {
color : #4183C4;
text-decoration: underline;
}
a.marginalized {
text-decoration: none;
}
a.self-link {
text-decoration: none;
}
h1#toctitle {
border-bottom: 1px solid #cccccc;
}
#TOC li {
margin-top: 1px;
margin-bottom: 1px;
}
#TOC ul>li:before { display: none; }
h3.subtitle { margin-top: -15px; }
h1:target { background-color: transparent; }
h2:target { background-color: transparent; }
h3:target { background-color: transparent; }
h4:target { background-color: transparent; }
h5:target { background-color: transparent; }
h6:target { background-color: transparent; }
code span.co { font-family: monospace; }
table tr {
background-color: white;
}
table tr:nth-child(2n) {
background-color: #f6f8fa;
}
#title-block-header > table tr:nth-child(2n) {
background-color: white;
}
td > div.sourceCode {
background-color: inherit;
}
table {
border-collapse: collapse;
}
table td, table th {
border: 1px solid #cccccc;
}
table th {
border-bottom: 1px solid black;
text-align: center;
}
table tr:first-child th {
border-top: 0;
}
table tr:last-child td {
border-bottom: 0;
}
table tr td:first-child,
table tr th:first-child {
border-left: 0;
}
table tr td:last-child,
table tr th:last-child {
border-right: 0;
}
table tbody tr:first-child td {
border-top: 1px solid black;
}
#title-block-header td { border: 0; }
@media all {
body {
margin: 2em;
}
}
@media screen and (min-width: 480px) {
body {
margin: 5em;
}
}
#refs code{padding-left: 0px; text-indent: 0px;}
:root {
--diff-ins: #e6ffed;
--diff-strongins: #acf2bd;
--diff-del: #ffdddd;
--diff-strongdel: #ff8888;
}
span.diffins {
background-color: var(--diff-strongins);
}
span.diffdel {
background-color: var(--diff-strongdel);
}
div.rm { text-decoration: line-through; }
div.rm code.sourceCode { text-decoration: line-through; }
div.addu, span.addu {
color: #006e28;
background-color: var(--diff-ins);
}

div.rm pre, div.add pre { background-color: #f6f8fa; }
div.addu pre { background-color: var(--diff-ins); }
div.add, div.add pre, div.add blockquote { background-color: var(--diff-ins); }
div.addu blockquote {
border-left: 4px solid #00a000;
padding: 0 15px;
color: #006e28;
text-decoration: none;
}
div.addu blockquote code.sourceCode { text-decoration: none; }
div.addu blockquote pre { text-decoration: none; }
div.addu blockquote pre code { text-decoration: none; }
code.diff span.va { color: #000000; background-color: var(--diff-ins); }
code.diff span.st { color: #000000; background-color: var(--diff-del); }
blockquote { background-color: #f6f8fa; }
</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">A type trait to detect reference binding to temporary</h1>

<table style="border:none;float:right">
  <tr>
    <td>Document #:</td>
    <td>P2255R1</td>
  </tr>
  <tr>
    <td>Date:</td>
    <td>2021-04-11</td>
  </tr>
  <tr>
    <td style="vertical-align:top">Project:</td>
    <td>Programming Language C++</td>
  </tr>
  <tr>
    <td style="vertical-align:top">Audience:</td>
    <td>
      EWG<br>
      LEWG<br>
    </td>
  </tr>
  <tr>
    <td style="vertical-align:top">Reply-to:</td>
    <td>
      Tim Song<br>&lt;<a href="mailto:t.canens.cpp@gmail.com" class="email">t.canens.cpp@gmail.com</a>&gt;<br>
    </td>
  </tr>
</table>

</header>
<div style="clear:both">
<div id="TOC" role="doc-toc">
<h1 id="toctitle">Contents</h1>
<ul>
<li><a href="#abstract"><span class="toc-section-number">1</span> Abstract<span></span></a></li>
<li><a href="#revision-history"><span class="toc-section-number">2</span> Revision history<span></span></a></li>
<li><a href="#in-brief"><span class="toc-section-number">3</span> In brief<span></span></a></li>
<li><a href="#motivation"><span class="toc-section-number">4</span> Motivation<span></span></a>
<ul>
<li><a href="#related-work"><span class="toc-section-number">4.1</span> Related work<span></span></a></li>
</ul></li>
<li><a href="#design-decisions"><span class="toc-section-number">5</span> Design decisions<span></span></a>
<ul>
<li><a href="#alternative-approaches"><span class="toc-section-number">5.1</span> Alternative approaches<span></span></a></li>
<li><a href="#two-type-traits"><span class="toc-section-number">5.2</span> Two type traits<span></span></a></li>
<li><a href="#treat-prvalues-as-distinct-from-xvalues"><span class="toc-section-number">5.3</span> Treat prvalues as distinct from xvalues<span></span></a></li>
<li><a href="#changing-invoker-and-is_invocable_r"><span class="toc-section-number">5.4</span> Changing <em><code class="sourceCode cpp">INVOKE<span class="op">&lt;</span>R<span class="op">&gt;</span></code></em> and <code class="sourceCode cpp">is_invocable_r</code><span></span></a></li>
<li><a href="#tuplepair-constructors-deletion-vs.-constraints"><span class="toc-section-number">5.5</span> <code class="sourceCode cpp">tuple</code>/<code class="sourceCode cpp">pair</code> constructors: deletion vs. constraints<span></span></a></li>
</ul></li>
<li><a href="#implementation-experience"><span class="toc-section-number">6</span> Implementation experience<span></span></a></li>
<li><a href="#wording"><span class="toc-section-number">7</span> Wording<span></span></a></li>
<li><a href="#bibliography"><span class="toc-section-number">8</span> References<span></span></a></li>
</ul>
</div>
<h1 data-number="1" style="border-bottom:1px solid #cccccc" id="abstract"><span class="header-section-number">1</span> Abstract<a href="#abstract" class="self-link"></a></h1>
<p>This paper proposes adding two new type traits with compiler support to detect when the initialization of a reference would bind it to a lifetime-extended temporary, and changing several standard library components to make such binding ill-formed when it would inevitably produce a dangling reference. This would resolve <span class="citation" data-cites="LWG2813">[<a href="#ref-LWG2813" role="doc-biblioref">LWG2813</a>]</span>.</p>
<h1 data-number="2" style="border-bottom:1px solid #cccccc" id="revision-history"><span class="header-section-number">2</span> Revision history<a href="#revision-history" class="self-link"></a></h1>
<ul>
<li>R1: Define the affected constructor of <code class="sourceCode cpp">tuple</code> and <code class="sourceCode cpp">pair</code> as deleted instead of removing them from overload resolution.</li>
</ul>
<h1 data-number="3" style="border-bottom:1px solid #cccccc" id="in-brief"><span class="header-section-number">3</span> In brief<a href="#in-brief" class="self-link"></a></h1>
<table>
<thead>
<tr class="header">
<th><div style="text-align:center">
<strong>Before</strong>
</div></th>
<th><div style="text-align:center">
<strong>After</strong>
</div></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><div class="sourceCode" id="cb1"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb1-1"><a href="#cb1-1"></a>std<span class="op">::</span>tuple<span class="op">&lt;</span><span class="kw">const</span> std<span class="op">::</span>string<span class="op">&amp;&gt;</span> x<span class="op">(</span><span class="st">&quot;hello&quot;</span><span class="op">)</span>;  <span class="co">// dangling</span></span>
<span id="cb1-2"><a href="#cb1-2"></a>std<span class="op">::</span>function<span class="op">&lt;</span><span class="kw">const</span> std<span class="op">::</span>string<span class="op">&amp;()&gt;</span> f <span class="op">=</span> <span class="op">[]</span> <span class="op">{</span> <span class="cf">return</span> <span class="st">&quot;&quot;</span>; <span class="op">}</span>; <span class="co">// OK</span></span>
<span id="cb1-3"><a href="#cb1-3"></a></span>
<span id="cb1-4"><a href="#cb1-4"></a>f<span class="op">()</span>;                                        <span class="co">// dangling</span></span></code></pre></div></td>
<td><div class="sourceCode" id="cb2"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb2-1"><a href="#cb2-1"></a>std<span class="op">::</span>tuple<span class="op">&lt;</span><span class="kw">const</span> std<span class="op">::</span>string<span class="op">&amp;&gt;</span> x<span class="op">(</span><span class="st">&quot;hello&quot;</span><span class="op">)</span>;   <span class="co">// ill-formed</span></span>
<span id="cb2-2"><a href="#cb2-2"></a>std<span class="op">::</span>function<span class="op">&lt;</span><span class="kw">const</span> std<span class="op">::</span>string<span class="op">&amp;()&gt;</span> f <span class="op">=</span> <span class="op">[]</span> <span class="op">{</span> <span class="cf">return</span> <span class="st">&quot;&quot;</span>; <span class="op">}</span>; <span class="co">// ill-formed</span></span></code></pre></div></td>
</tr>
</tbody>
</table>
<h1 data-number="4" style="border-bottom:1px solid #cccccc" id="motivation"><span class="header-section-number">4</span> Motivation<a href="#motivation" class="self-link"></a></h1>
<p>Generic libraries, including various parts of the standard library, need to initialize an entity of some user-provided type <code class="sourceCode cpp">T</code> from an expression of a potentially different type. When <code class="sourceCode cpp">T</code> is a reference type, this can easily create dangling references. This occurs, for instance, when a <code class="sourceCode cpp">std<span class="op">::</span>tuple<span class="op">&lt;</span><span class="kw">const</span> T<span class="op">&amp;&gt;</span></code> is initialized from something convertible to <code class="sourceCode cpp">T</code>:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb3-1"><a href="#cb3-1"></a>std<span class="op">::</span>tuple<span class="op">&lt;</span><span class="kw">const</span> std<span class="op">::</span>string<span class="op">&amp;&gt;</span> t<span class="op">(</span><span class="st">&quot;meow&quot;</span><span class="op">)</span>;</span></code></pre></div>
<p>This construction <em>always</em> creates a dangling reference, because the <code class="sourceCode cpp">std<span class="op">::</span>string</code> temporary is created <em>inside</em> the selected constructor of <code class="sourceCode cpp">tuple</code> (<code class="sourceCode cpp"><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span><span class="op">...</span> UTypes<span class="op">&gt;</span> tuple<span class="op">(</span>UTypes<span class="op">&amp;&amp;...)</span></code>), and not outside it. Thus, unlike <code class="sourceCode cpp">string_view</code>’s implicit conversion from rvalue strings, under no circumstances can this construction be correct.</p>
<p>Similarly, a <code class="sourceCode cpp">std<span class="op">::</span>function<span class="op">&lt;</span><span class="kw">const</span> string<span class="op">&amp;()&gt;</span></code> currently accepts any callable whose invocation produces something convertible to <code class="sourceCode cpp"><span class="kw">const</span> string<span class="op">&amp;</span></code>. However, if the invocation produces a <code class="sourceCode cpp">std<span class="op">::</span>string</code> or a <code class="sourceCode cpp"><span class="kw">const</span> <span class="dt">char</span><span class="op">*</span></code>, the returned reference would be bound to a temporary and dangle.</p>
<p>Moreover, in both of the above cases, the problematic reference binding occurs inside the standard library’s code, and some implementations are known to suppress warnings in such contexts.</p>
<h2 data-number="4.1" id="related-work"><span class="header-section-number">4.1</span> Related work<a href="#related-work" class="self-link"></a></h2>
<p><span class="citation" data-cites="P0932R1">[<a href="#ref-P0932R1" role="doc-biblioref">P0932R1</a>]</span> proposes modifying the constraints on <code class="sourceCode cpp">std<span class="op">::</span>function</code> to prevent such creation of dangling references. However, the proposed modification is incorrect (it has both false positives and false negatives), and correctly detecting all cases in which dangling references will be created without false positives is likely impossible or at least heroically difficult without compiler assistance, due to the existence of user-defined conversions.</p>
<p><span class="citation" data-cites="CWG1696">[<a href="#ref-CWG1696" role="doc-biblioref">CWG1696</a>]</span> changed the core language rules so that initialization of a reference data member in a <em>mem-initializer</em> is ill-formed if the initialization would bind it to a temporary expression, which is exactly the condition these traits seek to detect. However, the ill-formedness occurs outside a SFINAE context, so it is not usable in constraints, nor suitable as a <code class="sourceCode cpp"><span class="kw">static_assert</span></code> condition. Moreover, this requires having a class with a data member of reference type, which may not be suitable for user-defined types that want to represent references differently (to facilitate rebinding, for instance).</p>
<h1 data-number="5" style="border-bottom:1px solid #cccccc" id="design-decisions"><span class="header-section-number">5</span> Design decisions<a href="#design-decisions" class="self-link"></a></h1>
<h2 data-number="5.1" id="alternative-approaches"><span class="header-section-number">5.1</span> Alternative approaches<a href="#alternative-approaches" class="self-link"></a></h2>
<p>Similar to <span class="citation" data-cites="CWG1696">[<a href="#ref-CWG1696" role="doc-biblioref">CWG1696</a>]</span>, we can make returning a reference from a function ill-formed if it would be bound to a temporary. Just like <span class="citation" data-cites="CWG1696">[<a href="#ref-CWG1696" role="doc-biblioref">CWG1696</a>]</span>, this cannot be used as the basis of a constraint or as a <code class="sourceCode cpp"><span class="kw">static_assert</span></code> condition. Additionally, such a change requires library wording to react, as <code class="sourceCode cpp">is_convertible</code> is currently defined in terms of such a return statement. While such a language change may be desirable, it is neither necessary nor sufficient to accomplish the goals of this paper. It can be proposed separately if desired.</p>
<p>During a previous EWG telecon discussion, some have suggested inventing some sort of new initialization rules, perhaps with new keywords like <code class="sourceCode cpp">direct_cast</code>. The author of this paper is unwilling to spare a kidney for any new keyword in this area, and such a construct can easily be implemented in the library if the traits are available. Moreover, changing initialization rules is a risky endeavor; such changes frequently come with unintended consequences (for recent examples, see <span class="citation" data-cites="gcc-pr95153">[<a href="#ref-gcc-pr95153" role="doc-biblioref">gcc-pr95153</a>]</span> and <span class="citation" data-cites="LWG3440">[<a href="#ref-LWG3440" role="doc-biblioref">LWG3440</a>]</span>). It’s not at all clear that the marginal benefit from such changes (relative to the trait-based approach) justifies the risk.</p>
<h2 data-number="5.2" id="two-type-traits"><span class="header-section-number">5.2</span> Two type traits<a href="#two-type-traits" class="self-link"></a></h2>
<p>This paper proposes two traits, <code class="sourceCode cpp">reference_constructs_from_temporary</code> and <code class="sourceCode cpp">reference_converts_from_temporary</code>, to cover both (non-list) direct-initialization and copy-initialization. The former is useful in classes like <code class="sourceCode cpp">std<span class="op">::</span>tuple</code> and <code class="sourceCode cpp">std<span class="op">::</span>pair</code> where <code class="sourceCode cpp"><span class="kw">explicit</span></code> constructors and conversion functions may be used; the latter is useful for <em><code class="sourceCode cpp">INVOKE<span class="op">&lt;</span>R<span class="op">&gt;</span></code></em> (e.g., <code class="sourceCode cpp">std<span class="op">::</span>function</code>) where only implicit conversions are considered.</p>
<p>As is customary in the library traits, “construct” is used to denote direct-initialization and “convert” is used to denote copy-initialization.</p>
<h2 data-number="5.3" id="treat-prvalues-as-distinct-from-xvalues"><span class="header-section-number">5.3</span> Treat prvalues as distinct from xvalues<a href="#treat-prvalues-as-distinct-from-xvalues" class="self-link"></a></h2>
<p>Unlike most library type traits, this paper proposes that the traits handle prvalues and xvalues differently: <code class="sourceCode cpp">reference_converts_from_temporary<span class="op">&lt;</span><span class="dt">int</span><span class="op">&amp;&amp;</span>, <span class="dt">int</span><span class="op">&gt;</span></code> is <code class="sourceCode cpp"><span class="kw">true</span></code>, while <code class="sourceCode cpp">reference_converts_from_temporary<span class="op">&lt;</span><span class="dt">int</span><span class="op">&amp;&amp;</span>, <span class="dt">int</span><span class="op">&amp;&amp;&gt;</span></code> is <code class="sourceCode cpp"><span class="kw">false</span></code>. This is useful for <em><code class="sourceCode cpp">INVOKE<span class="op">&lt;</span>R<span class="op">&gt;</span></code></em>; binding an rvalue reference to the result of an xvalue-returning function is not incorrect (as long as the function does not return a dangling reference itself), but binding it to a prvalue (or a temporary object materialized therefrom) would be.</p>
<h2 data-number="5.4" id="changing-invoker-and-is_invocable_r"><span class="header-section-number">5.4</span> Changing <em><code class="sourceCode cpp">INVOKE<span class="op">&lt;</span>R<span class="op">&gt;</span></code></em> and <code class="sourceCode cpp">is_invocable_r</code><a href="#changing-invoker-and-is_invocable_r" class="self-link"></a></h2>
<p>Changing the definition of <em><code class="sourceCode cpp">INVOKE<span class="op">&lt;</span>R<span class="op">&gt;</span></code></em> as proposed means that <code class="sourceCode cpp">is_invocable_r</code> will also change its meaning, and there will be cases where <code class="sourceCode cpp">R v <span class="op">=</span> std<span class="op">::</span>invoke<span class="op">(</span><em>args</em><span class="op">...)</span>;</code> is valid but <code class="sourceCode cpp">is_invocable_r_v<span class="op">&lt;</span>R, <span class="kw">decltype</span><span class="op">((</span><em>args</em><span class="op">))...&gt;</span></code> is <code class="sourceCode cpp"><span class="kw">false</span></code>:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb4-1"><a href="#cb4-1"></a><span class="kw">auto</span> f <span class="op">=</span> <span class="op">[]{</span> <span class="cf">return</span> <span class="st">&quot;hello&quot;</span>; <span class="op">}</span>;</span>
<span id="cb4-2"><a href="#cb4-2"></a></span>
<span id="cb4-3"><a href="#cb4-3"></a><span class="kw">const</span> std<span class="op">::</span>string<span class="op">&amp;</span> v <span class="op">=</span> std<span class="op">::</span>invoke<span class="op">(</span>f<span class="op">)</span>;                              <span class="co">// OK</span></span>
<span id="cb4-4"><a href="#cb4-4"></a><span class="kw">static_assert</span><span class="op">(</span>is_invocable_r_v<span class="op">&lt;</span><span class="kw">const</span> std<span class="op">::</span>string<span class="op">&amp;</span>, <span class="kw">decltype</span><span class="op">((</span>f<span class="op">))&gt;)</span>; <span class="co">// now fails</span></span></code></pre></div>
<p>However, we already have the reverse case today (<code class="sourceCode cpp">is_invocable_r_v</code> is <code class="sourceCode cpp"><span class="kw">true</span></code> but the declaration isn’t valid, which is the case if <code class="sourceCode cpp">R</code> is <em>cv</em> <code class="sourceCode cpp"><span class="dt">void</span></code>), so generic code already cannot use <code class="sourceCode cpp">is_invocable_r</code> for this purpose.</p>
<p>More importantly, actual usage of <em><code class="sourceCode cpp">INVOKE<span class="op">&lt;</span>R<span class="op">&gt;</span></code></em> in the standard clearly suggests that changing its definition is the right thing to do. It is currently used in four places:</p>
<ul>
<li><code class="sourceCode cpp">std<span class="op">::</span>function</code></li>
<li><code class="sourceCode cpp">std<span class="op">::</span>visit<span class="op">&lt;</span>R<span class="op">&gt;</span></code></li>
<li><code class="sourceCode cpp">std<span class="op">::</span>bind<span class="op">&lt;</span>R<span class="op">&gt;</span></code></li>
<li><code class="sourceCode cpp">std<span class="op">::</span>packaged_task</code></li>
</ul>
<p>In none of them is producing a temporary-bound reference ever correct. Nor would it be correct for the proposed <code class="sourceCode cpp">std<span class="op">::</span>invoke_r</code> (<span class="citation" data-cites="P2136R1">[<a href="#ref-P2136R1" role="doc-biblioref">P2136R1</a>]</span>), <code class="sourceCode cpp">std<span class="op">::</span>any_invocable</code> (<span class="citation" data-cites="P0288R7">[<a href="#ref-P0288R7" role="doc-biblioref">P0288R7</a>]</span>), or <code class="sourceCode cpp">std<span class="op">::</span>function_ref</code> (<span class="citation" data-cites="P0792R5">[<a href="#ref-P0792R5" role="doc-biblioref">P0792R5</a>]</span>).</p>
<h2 data-number="5.5" id="tuplepair-constructors-deletion-vs.-constraints"><span class="header-section-number">5.5</span> <code class="sourceCode cpp">tuple</code>/<code class="sourceCode cpp">pair</code> constructors: deletion vs. constraints<a href="#tuplepair-constructors-deletion-vs.-constraints" class="self-link"></a></h2>
<p>The wording in R0 of this paper added constraints to the constructor templates of <code class="sourceCode cpp">tuple</code> and <code class="sourceCode cpp">pair</code> to remove them from overload resolution when the initialization would require binding to a materialized temporary. During LEWG mailing list review, it was pointed out that this would cause the construction to fall back to the <code class="sourceCode cpp">tuple<span class="op">(</span><span class="kw">const</span> Types<span class="op">&amp;...)</span></code> constructor instead, with the result that a temporary is created <em>outside</em> the <code class="sourceCode cpp">tuple</code> constructor and then bound to the reference.</p>
<p>While there are plausible cases where doing this is valid (for instance, <code class="sourceCode cpp">f<span class="op">(</span>tuple<span class="op">&lt;</span><span class="kw">const</span> string<span class="op">&amp;&gt;(</span><span class="st">&quot;meow&quot;</span><span class="op">))</span></code>, where the temporary string will live until the end of the full-expression), the risk of misuse is great enough that this revision proposes that the constructor be deleted in this scenario instead. Deleting the constructor still allows the condition to be observable to type traits and constraints, and avoids silent fallback to a questionable overload. Advanced users who desire such a binding can still explicitly convert the string themselves, which is what they have to do for correctness today anyway.</p>
<h1 data-number="6" style="border-bottom:1px solid #cccccc" id="implementation-experience"><span class="header-section-number">6</span> Implementation experience<a href="#implementation-experience" class="self-link"></a></h1>
<p>Clang has a <code class="sourceCode cpp">__reference_binds_to_temporary</code> intrinsic that partially implements the direct-initialization variant of the proposed trait: it does not implement the part that involves reference binding to a prvalue of the same or derived type.</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb5-1"><a href="#cb5-1"></a><span class="kw">static_assert</span><span class="op">(</span>__reference_binds_to_temporary<span class="op">(</span>std<span class="op">::</span>string <span class="kw">const</span> <span class="op">&amp;</span>, <span class="kw">const</span> <span class="dt">char</span><span class="op">*))</span>;</span>
<span id="cb5-2"><a href="#cb5-2"></a><span class="kw">static_assert</span><span class="op">(</span><span class="kw">not</span> __reference_binds_to_temporary<span class="op">(</span><span class="dt">int</span><span class="op">&amp;&amp;</span>, <span class="dt">int</span><span class="op">))</span>;</span>
<span id="cb5-3"><a href="#cb5-3"></a><span class="kw">static_assert</span><span class="op">(</span><span class="kw">not</span> __reference_binds_to_temporary<span class="op">(</span>Base <span class="kw">const</span><span class="op">&amp;</span>, Derived<span class="op">))</span>;</span></code></pre></div>
<p>However, that part can be done in the library if required, by checking that</p>
<ul>
<li>the destination type <code class="sourceCode cpp">T</code> is a reference type;</li>
<li>the source type <code class="sourceCode cpp">U</code> is not a reference type (i.e., it represents a prvalue);</li>
<li><code class="sourceCode cpp">is_convertible_v<span class="op">&lt;</span>remove_cvref_t<span class="op">&lt;</span>U<span class="op">&gt;*</span>, remove_cvref_t<span class="op">&lt;</span>T<span class="op">&gt;*&gt;</span></code> is <code class="sourceCode cpp"><span class="kw">true</span></code>.</li>
</ul>
<h1 data-number="7" style="border-bottom:1px solid #cccccc" id="wording"><span class="header-section-number">7</span> Wording<a href="#wording" class="self-link"></a></h1>
<p>This wording is relative to <span class="citation" data-cites="N4868">[<a href="#ref-N4868" role="doc-biblioref">N4868</a>]</span>.</p>
<div>
<ol type="1">
<li>Edit <span>20.15.3 <a href="https://wg21.link/meta.type.synop">[meta.type.synop]</a></span>, header <code class="sourceCode cpp"><span class="op">&lt;</span>type_traits<span class="op">&gt;</span></code> synopsis, as indicated:</li>
</ol>
<blockquote>
<div>
<div class="sourceCode" id="cb6"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb6-1"><a href="#cb6-1"></a> namespace std {</span>
<span id="cb6-2"><a href="#cb6-2"></a>   <em>[…]</em></span>
<span id="cb6-3"><a href="#cb6-3"></a>   template&lt;class T&gt; struct has_unique_object_representations;</span>
<span id="cb6-4"><a href="#cb6-4"></a></span>
<span id="cb6-5"><a href="#cb6-5"></a><span class="va">+  template&lt;class T, class U&gt; struct reference_constructs_from_temporary;</span></span>
<span id="cb6-6"><a href="#cb6-6"></a><span class="va">+  template&lt;class T, class U&gt; struct reference_converts_from_temporary;</span></span>
<span id="cb6-7"><a href="#cb6-7"></a></span>
<span id="cb6-8"><a href="#cb6-8"></a>   <em>[…]</em></span>
<span id="cb6-9"><a href="#cb6-9"></a></span>
<span id="cb6-10"><a href="#cb6-10"></a>   template&lt;class T&gt;</span>
<span id="cb6-11"><a href="#cb6-11"></a>     inline constexpr bool has_unique_object_representations_v</span>
<span id="cb6-12"><a href="#cb6-12"></a>       = has_unique_object_representations&lt;T&gt;::value;</span>
<span id="cb6-13"><a href="#cb6-13"></a></span>
<span id="cb6-14"><a href="#cb6-14"></a><span class="va">+  template&lt;class T, class U&gt;</span></span>
<span id="cb6-15"><a href="#cb6-15"></a><span class="va">+    inline constexpr bool reference_constructs_from_temporary_v</span></span>
<span id="cb6-16"><a href="#cb6-16"></a><span class="va">+      = reference_constructs_from_temporary&lt;T, U&gt;::value;</span></span>
<span id="cb6-17"><a href="#cb6-17"></a><span class="va">+  template&lt;class T, class U&gt;</span></span>
<span id="cb6-18"><a href="#cb6-18"></a><span class="va">+    inline constexpr bool reference_converts_from_temporary_v</span></span>
<span id="cb6-19"><a href="#cb6-19"></a><span class="va">+      = reference_converts_from_temporary&lt;T, U&gt;::value;</span></span>
<span id="cb6-20"><a href="#cb6-20"></a></span>
<span id="cb6-21"><a href="#cb6-21"></a>   <em>[…]</em></span>
<span id="cb6-22"><a href="#cb6-22"></a> }</span></code></pre></div>
</div>
</blockquote>
<ol start="2" type="1">
<li>In <span>20.15.5.4 <a href="https://wg21.link/meta.unary.prop">[meta.unary.prop]</a></span>, add the following after p4:</li>
</ol>
<blockquote>
<div class="add" style="color: #006e28">
<p><span class="marginalizedparent"><a class="marginalized">?</a></span> For the purpose of defining the templates in this subclause, let <em><code class="sourceCode default">VAL&lt;T&gt;</code></em> for some type <em><code class="sourceCode default">T</code></em> be an expression defined as follows:</p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">(?.1)</a></span> If <em><code class="sourceCode default">T</code></em> is a reference or function type, <em><code class="sourceCode default">VAL&lt;T&gt;</code></em> is an expression with the same type and value category as <code class="sourceCode default">declval&lt;<em>T</em>&gt;()</code>. <!-- Can make this "referenceable function type", but doesn't super matter --></li>
<li><span class="marginalizedparent"><a class="marginalized">(?.2)</a></span> Otherwise, <em><code class="sourceCode default">VAL&lt;T&gt;</code></em> is a prvalue that initially has type <em><code class="sourceCode default">T</code></em>. <span class="note"><span>[ <em>Note ?:</em> </span>If <em><code class="sourceCode default">T</code></em> is cv-qualified, the cv-qualification is subject to adjustment (<span>7.2.2 <a href="https://wg21.link/expr.type">[expr.type]</a></span>).<span> — <em>end note</em> ]</span></span> <!-- Why not declval<T(&)()>()()? Because that doesn't work for array or function types.--></li>
</ul>

</div>
</blockquote>
<ol start="3" type="1">
<li>In <span>20.15.5.4 <a href="https://wg21.link/meta.unary.prop">[meta.unary.prop]</a></span>, Table 49 [tab:meta.unary.prop], add the following:</li>
</ol>
<blockquote>
<table>
<thead>
<tr class="header">
<th>Template<a href="#template" class="self-link"></a></th>
<th>Condition<a href="#condition" class="self-link"></a></th>
<th>Preconditions<a href="#preconditions" class="self-link"></a></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><div class="ltcell">
<div class="sourceCode" id="cb7"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb7-1"><a href="#cb7-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> T, <span class="kw">class</span> U<span class="op">&gt;</span></span>
<span id="cb7-2"><a href="#cb7-2"></a><span class="kw">struct</span> reference_constructs_from_temporary;</span></code></pre></div>
</div></td>
<td><div class="ltcell">
<p><code class="sourceCode cpp">conjunction_v<span class="op">&lt;</span>is_reference<span class="op">&lt;</span>T<span class="op">&gt;</span>, is_constructible<span class="op">&lt;</span>T, U<span class="op">&gt;&gt;</span></code> is <code class="sourceCode cpp"><span class="kw">true</span></code>, and the initialization <code class="sourceCode cpp">T t<span class="op">(</span><em>VAL</em><span class="op">&lt;</span>U<span class="op">&gt;)</span>;</code> binds <code class="sourceCode cpp">t</code> to a temporary object whose lifetime is extended (<span>6.7.7 <a href="https://wg21.link/class.temporary">[class.temporary]</a></span>).</p>
</div></td>
<td><div class="ltcell">
<p><code class="sourceCode cpp">T</code> and <code class="sourceCode cpp">U</code> shall be complete types, <em>cv</em> <code class="sourceCode cpp"><span class="dt">void</span></code>, or arrays of unknown bound.</p>
</div></td>
</tr>
<tr class="even">
<td><div class="ltcell">
<div class="sourceCode" id="cb8"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb8-1"><a href="#cb8-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> T, <span class="kw">class</span> U<span class="op">&gt;</span></span>
<span id="cb8-2"><a href="#cb8-2"></a><span class="kw">struct</span> reference_converts_from_temporary;</span></code></pre></div>
</div></td>
<td><div class="ltcell">
<p><code class="sourceCode cpp">conjunction_v<span class="op">&lt;</span>is_reference<span class="op">&lt;</span>T<span class="op">&gt;</span>, is_convertible<span class="op">&lt;</span>U, T<span class="op">&gt;&gt;</span></code> is <code class="sourceCode cpp"><span class="kw">true</span></code>, and the initialization <code class="sourceCode cpp">T t <span class="op">=</span> <em>VAL</em><span class="op">&lt;</span>U<span class="op">&gt;</span>;</code> binds <code class="sourceCode cpp">t</code> to a temporary object whose lifetime is extended (<span>6.7.7 <a href="https://wg21.link/class.temporary">[class.temporary]</a></span>).</p>
</div></td>
<td><div class="ltcell">
<p><code class="sourceCode cpp">T</code> and <code class="sourceCode cpp">U</code> shall be complete types, <em>cv</em> <code class="sourceCode cpp"><span class="dt">void</span></code>, or arrays of unknown bound.</p>
</div></td>
</tr>
</tbody>
</table>
</blockquote>
<ol start="4" type="1">
<li>Edit <span>20.4.2 <a href="https://wg21.link/pairs.pair">[pairs.pair]</a></span> as indicated:</li>
</ol>
<blockquote>
<div>
<div class="sourceCode" id="cb9"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb9-1"><a href="#cb9-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> U1, <span class="kw">class</span> U2<span class="op">&gt;</span> <span class="kw">constexpr</span> <span class="kw">explicit</span><span class="op">(</span><em>see below</em><span class="op">)</span> pair<span class="op">(</span>U1<span class="op">&amp;&amp;</span> x, U2<span class="op">&amp;&amp;</span> y<span class="op">)</span>;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">11</a></span> <em>Constraints:</em></p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">(11.1)</a></span> <code class="sourceCode cpp">is_constructible_v<span class="op">&lt;</span>first_type, U1<span class="op">&gt;</span></code> is <code class="sourceCode cpp"><span class="kw">true</span></code> and</li>
<li><span class="marginalizedparent"><a class="marginalized">(11.2)</a></span> <code class="sourceCode cpp">is_constructible_v<span class="op">&lt;</span>second_type, U2<span class="op">&gt;</span></code> is <code class="sourceCode cpp"><span class="kw">true</span></code>.</li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">12</a></span> <em>Effects:</em> Initializes <code class="sourceCode cpp">first</code> with <code class="sourceCode cpp">std<span class="op">::</span>forward<span class="op">&lt;</span>U1<span class="op">&gt;(</span>x<span class="op">)</span></code> and <code class="sourceCode cpp">second</code> with <code class="sourceCode cpp">std<span class="op">::</span>forward<span class="op">&lt;</span>U2<span class="op">&gt;(</span>y<span class="op">)</span></code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">13</a></span> <em>Remarks:</em> The expression inside <code class="sourceCode cpp"><span class="kw">explicit</span></code> is equivalent to: <code class="sourceCode cpp"><span class="op">!</span>is_convertible_v<span class="op">&lt;</span>U1, first_type<span class="op">&gt;</span> <span class="op">||</span> <span class="op">!</span>is_convertible_v<span class="op">&lt;</span>U2, second_type<span class="op">&gt;</span></code>. <span class="diffins">This constructor is defined as deleted if <code class="sourceCode cpp">reference_constructs_from_temporary_v<span class="op">&lt;</span>first_type, U1<span class="op">&amp;&amp;&gt;</span></code> is <code class="sourceCode cpp"><span class="kw">true</span></code> or <code class="sourceCode cpp">reference_constructs_from_temporary_v<span class="op">&lt;</span>second_type, U2<span class="op">&amp;&amp;&gt;</span></code> is <code class="sourceCode cpp"><span class="kw">true</span></code>.</span></p>
</blockquote>
<div class="sourceCode" id="cb10"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb10-1"><a href="#cb10-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> U1, <span class="kw">class</span> U2<span class="op">&gt;</span> <span class="kw">constexpr</span> <span class="kw">explicit</span><span class="op">(</span><em>see below</em><span class="op">)</span> pair<span class="op">(</span><span class="kw">const</span> pair<span class="op">&lt;</span>U1, U2<span class="op">&gt;&amp;</span> p<span class="op">)</span>;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">14</a></span> <em>Constraints:</em></p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">(14.1)</a></span> <code class="sourceCode cpp">is_constructible_v<span class="op">&lt;</span>first_type, <span class="kw">const</span> U1<span class="op">&amp;&gt;</span></code> is <code class="sourceCode cpp"><span class="kw">true</span></code> and</li>
<li><span class="marginalizedparent"><a class="marginalized">(14.2)</a></span> <code class="sourceCode cpp">is_constructible_v<span class="op">&lt;</span>second_type, <span class="kw">const</span> U2<span class="op">&amp;&gt;</span></code> is <code class="sourceCode cpp"><span class="kw">true</span></code>.</li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">15</a></span> <em>Effects:</em> Initializes members from the corresponding members of the argument.</p>
<p><span class="marginalizedparent"><a class="marginalized">16</a></span> <em>Remarks:</em> The expression inside <code class="sourceCode cpp"><span class="kw">explicit</span></code> is equivalent to: <code class="sourceCode cpp"><span class="op">!</span>is_convertible_v<span class="op">&lt;</span><span class="kw">const</span> U1<span class="op">&amp;</span>, first_type<span class="op">&gt;</span> <span class="op">||</span> <span class="op">!</span>is_convertible_v<span class="op">&lt;</span><span class="kw">const</span> U2<span class="op">&amp;</span>, second_type<span class="op">&gt;</span></code>. <span class="diffins">This constructor is defined as deleted if <code class="sourceCode cpp">reference_constructs_from_temporary_v<span class="op">&lt;</span>first_type, <span class="kw">const</span> U1<span class="op">&amp;&gt;</span></code> is <code class="sourceCode cpp"><span class="kw">true</span></code> or <code class="sourceCode cpp">reference_constructs_from_temporary_v<span class="op">&lt;</span>second_type, <span class="kw">const</span> U2<span class="op">&amp;&gt;</span></code> is <code class="sourceCode cpp"><span class="kw">true</span></code>.</span></p>
</blockquote>
<div class="sourceCode" id="cb11"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb11-1"><a href="#cb11-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> U1, <span class="kw">class</span> U2<span class="op">&gt;</span> <span class="kw">constexpr</span> <span class="kw">explicit</span><span class="op">(</span><em>see below</em><span class="op">)</span> pair<span class="op">(</span>pair<span class="op">&lt;</span>U1, U2<span class="op">&gt;&amp;&amp;</span> p<span class="op">)</span>;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">17</a></span> <em>Constraints:</em></p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">(17.1)</a></span> <code class="sourceCode cpp">is_constructible_v<span class="op">&lt;</span>first_type, U1<span class="op">&gt;</span></code> is <code class="sourceCode cpp"><span class="kw">true</span></code> and</li>
<li><span class="marginalizedparent"><a class="marginalized">(17.2)</a></span> <code class="sourceCode cpp">is_constructible_v<span class="op">&lt;</span>second_type, U2<span class="op">&gt;</span></code> is <code class="sourceCode cpp"><span class="kw">true</span></code>.</li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">18</a></span> <em>Effects:</em> Initializes <code class="sourceCode cpp">first</code> with <code class="sourceCode cpp">std<span class="op">::</span>forward<span class="op">&lt;</span>U1<span class="op">&gt;(</span>p<span class="op">.</span>first<span class="op">)</span></code> and <code class="sourceCode cpp">second</code> with <code class="sourceCode cpp">std<span class="op">::</span>forward<span class="op">&lt;</span>U2<span class="op">&gt;(</span>p<span class="op">.</span>second<span class="op">)</span></code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">19</a></span> <em>Remarks:</em> The expression inside <code class="sourceCode cpp"><span class="kw">explicit</span></code> is equivalent to: <code class="sourceCode cpp"><span class="op">!</span>is_convertible_v<span class="op">&lt;</span>U1, first_type<span class="op">&gt;</span> <span class="op">||</span> <span class="op">!</span>is_convertible_v<span class="op">&lt;</span>U2, second_type<span class="op">&gt;</span></code>. <span class="diffins">This constructor is defined as deleted if <code class="sourceCode cpp">reference_constructs_from_temporary_v<span class="op">&lt;</span>first_type, U1<span class="op">&amp;&amp;&gt;</span></code> is <code class="sourceCode cpp"><span class="kw">true</span></code> or <code class="sourceCode cpp">reference_constructs_from_temporary_v<span class="op">&lt;</span>second_type, U2<span class="op">&amp;&amp;&gt;</span></code> is <code class="sourceCode cpp"><span class="kw">true</span></code>.</span></p>
</blockquote>
<div class="sourceCode" id="cb12"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb12-1"><a href="#cb12-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span><span class="op">...</span> Args1, <span class="kw">class</span><span class="op">...</span> Args2<span class="op">&gt;</span></span>
<span id="cb12-2"><a href="#cb12-2"></a>  <span class="kw">constexpr</span> pair<span class="op">(</span>piecewise_construct_t,</span>
<span id="cb12-3"><a href="#cb12-3"></a>                 tuple<span class="op">&lt;</span>Args1<span class="op">...&gt;</span> first_args, tuple<span class="op">&lt;</span>Args2<span class="op">...&gt;</span> second_args<span class="op">)</span>;</span></code></pre></div>
<blockquote>
<p><span class="draftnote" style="color: #01796F">[ Drafting note: No changes are needed here because this is a <em>Mandates:</em> and the initialization is ill-formed under <span class="citation" data-cites="CWG1696">[<a href="#ref-CWG1696" role="doc-biblioref">CWG1696</a>]</span>. ]</span></p>
<p><span class="marginalizedparent"><a class="marginalized">20</a></span> <em>Mandates:</em></p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">(20.1)</a></span> <code class="sourceCode cpp">is_constructible_v<span class="op">&lt;</span>first_type, Args1<span class="op">...&gt;</span></code> is <code class="sourceCode cpp"><span class="kw">true</span></code> and</li>
<li><span class="marginalizedparent"><a class="marginalized">(20.2)</a></span> <code class="sourceCode cpp">is_constructible_v<span class="op">&lt;</span>second_type, Args2<span class="op">...&gt;</span></code> is <code class="sourceCode cpp"><span class="kw">true</span></code>.</li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">21</a></span> <em>Effects:</em> Initializes <code class="sourceCode cpp">first</code> with arguments of types <code class="sourceCode cpp">Args1<span class="op">...</span></code> obtained by forwarding the elements of <code class="sourceCode cpp">first_args</code> and initializes <code class="sourceCode cpp">second</code> with arguments of types <code class="sourceCode cpp">Args2<span class="op">...</span></code> obtained by forwarding the elements of <code class="sourceCode cpp">second_args</code>. (Here, forwarding an element <code class="sourceCode cpp">x</code> of type <code class="sourceCode cpp">U</code> within a tuple object means calling <code class="sourceCode cpp">std<span class="op">::</span>forward<span class="op">&lt;</span>U<span class="op">&gt;(</span>x<span class="op">)</span></code>.) This form of construction, whereby constructor arguments for <code class="sourceCode cpp">first</code> and <code class="sourceCode cpp">second</code> are each provided in a separate <code class="sourceCode cpp">tuple</code> object, is called <em>piecewise construction</em>.</p>
</blockquote>
</div>
</blockquote>
<ol start="5" type="1">
<li>Edit <span>20.5.3.1 <a href="https://wg21.link/tuple.cnstr">[tuple.cnstr]</a></span> as indicated:</li>
</ol>
<blockquote>
<div>
<div class="sourceCode" id="cb13"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb13-1"><a href="#cb13-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span><span class="op">...</span> UTypes<span class="op">&gt;</span> <span class="kw">constexpr</span> <span class="kw">explicit</span><span class="op">(</span><em>see below</em><span class="op">)</span> tuple<span class="op">(</span>UTypes<span class="op">&amp;&amp;...</span> u<span class="op">)</span>;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">11</a></span> <em>Constraints:</em> <code class="sourceCode cpp"><span class="kw">sizeof</span><span class="op">...(</span>Types<span class="op">)</span></code> equals <code class="sourceCode cpp"><span class="kw">sizeof</span><span class="op">...(</span>UTypes<span class="op">)</span></code> and <code class="sourceCode cpp"><span class="kw">sizeof</span><span class="op">...(</span>Types<span class="op">)</span></code> ≥ 1 and <code class="sourceCode cpp">is_constructible_v<span class="op">&lt;</span>T<em><sub>i</sub></em>, U<em><sub>i</sub></em><span class="op">&gt;</span></code> is <code class="sourceCode cpp"><span class="kw">true</span></code> for all <em>i</em>.</p>
<p><span class="marginalizedparent"><a class="marginalized">12</a></span> <em>Effects:</em> Initializes the elements in the tuple with the corresponding value in <code class="sourceCode cpp">std<span class="op">::</span>forward<span class="op">&lt;</span>UTypes<span class="op">&gt;(</span>u<span class="op">)</span></code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">13</a></span> <em>Remarks:</em> The expression inside <code class="sourceCode cpp"><span class="kw">explicit</span></code> is equivalent to: <code class="sourceCode cpp"><span class="op">!</span>conjunction_v<span class="op">&lt;</span>is_convertible<span class="op">&lt;</span>UTypes, Types<span class="op">&gt;...&gt;</span></code>. <span class="diffins">This constructor is defined as deleted if <code class="sourceCode cpp"><span class="op">(</span>reference_constructs_from_temporary_v<span class="op">&lt;</span>Types, UTypes<span class="op">&amp;&amp;&gt;</span> <span class="op">||</span> <span class="op">...)</span></code> is <code class="sourceCode cpp"><span class="kw">true</span></code>.</span></p>
</blockquote>
</div>
<p>[…]</p>
<div>
<div class="sourceCode" id="cb14"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb14-1"><a href="#cb14-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span><span class="op">...</span> UTypes<span class="op">&gt;</span> <span class="kw">constexpr</span> <span class="kw">explicit</span><span class="op">(</span><em>see below</em><span class="op">)</span> tuple<span class="op">(</span><span class="kw">const</span> tuple<span class="op">&lt;</span>UTypes<span class="op">...&gt;&amp;</span> u<span class="op">)</span>;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">18</a></span> <em>Constraints:</em></p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">(18.1)</a></span> <code class="sourceCode cpp"><span class="kw">sizeof</span><span class="op">...(</span>Types<span class="op">)</span></code> equals <code class="sourceCode cpp"><span class="kw">sizeof</span><span class="op">...(</span>UTypes</code>)<span class="diffins">,</span> and</li>
<li><span class="marginalizedparent"><a class="marginalized">(18.2)</a></span><code class="sourceCode cpp">is_constructible_v<span class="op">&lt;</span>T<em><sub>i</sub></em>, <span class="kw">const</span> U<em><sub>i</sub></em><span class="op">&amp;&gt;</span></code> is <code class="sourceCode cpp"><span class="kw">true</span></code> for all <em>i</em>, and</li>
<li><span class="marginalizedparent"><a class="marginalized">(18.3)</a></span> either <code class="sourceCode cpp"><span class="kw">sizeof</span><span class="op">...(</span>Types<span class="op">)</span></code> is not 1, or (when <code class="sourceCode cpp">Types<span class="op">...</span></code> expands to <code class="sourceCode cpp">T</code> and <code class="sourceCode cpp">UTypes<span class="op">...</span></code> expands to <code class="sourceCode cpp">U</code>) <code class="sourceCode cpp">is_convertible_v<span class="op">&lt;</span><span class="kw">const</span> tuple<span class="op">&lt;</span>U<span class="op">&gt;&amp;</span>, T<span class="op">&gt;</span></code>, <code class="sourceCode cpp">is_constructible_v<span class="op">&lt;</span>T, <span class="kw">const</span> tuple<span class="op">&lt;</span>U<span class="op">&gt;&amp;&gt;</span></code>, and <code class="sourceCode cpp">is_same_v<span class="op">&lt;</span>T, U<span class="op">&gt;</span></code> are all <code class="sourceCode cpp"><span class="kw">false</span></code>.</li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">19</a></span> <em>Effects:</em> Initializes each element of <code class="sourceCode cpp"><span class="op">*</span><span class="kw">this</span></code> with the corresponding element of <code class="sourceCode cpp">u</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">20</a></span> <em>Remarks:</em> The expression inside <code class="sourceCode cpp"><span class="kw">explicit</span></code> is equivalent to: <code class="sourceCode cpp"><span class="op">!</span>conjunction_v<span class="op">&lt;</span>is_convertible<span class="op">&lt;</span><span class="kw">const</span> UTypes<span class="op">&amp;</span>, Types<span class="op">&gt;...&gt;</span></code>. <span class="diffins">This constructor is defined as deleted if <code class="sourceCode cpp"><span class="op">(</span>reference_constructs_from_temporary_v<span class="op">&lt;</span>Types, <span class="kw">const</span> UTypes<span class="op">&amp;&gt;</span> <span class="op">||</span> <span class="op">...)</span></code> is <code class="sourceCode cpp"><span class="kw">true</span></code>.</span></p>
</blockquote>
<div class="sourceCode" id="cb15"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb15-1"><a href="#cb15-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span><span class="op">...</span> UTypes<span class="op">&gt;</span> <span class="kw">constexpr</span> <span class="kw">explicit</span><span class="op">(</span><em>see below</em><span class="op">)</span> tuple<span class="op">(</span>tuple<span class="op">&lt;</span>UTypes<span class="op">...&gt;&amp;&amp;</span> u<span class="op">)</span>;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">21</a></span> <em>Constraints:</em></p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">(21.1)</a></span> <code class="sourceCode cpp"><span class="kw">sizeof</span><span class="op">...(</span>Types<span class="op">)</span></code> equals <code class="sourceCode cpp"><span class="kw">sizeof</span><span class="op">...(</span>UTypes</code>), and</li>
<li><span class="marginalizedparent"><a class="marginalized">(21.2)</a></span><code class="sourceCode cpp">is_constructible_v<span class="op">&lt;</span>T<em><sub>i</sub></em>, U<em><sub>i</sub></em><span class="op">&gt;</span></code> is <code class="sourceCode cpp"><span class="kw">true</span></code> for all <em>i</em>, and</li>
<li><span class="marginalizedparent"><a class="marginalized">(21.3)</a></span> either <code class="sourceCode cpp"><span class="kw">sizeof</span><span class="op">...(</span>Types<span class="op">)</span></code> is not 1, or (when <code class="sourceCode cpp">Types<span class="op">...</span></code> expands to <code class="sourceCode cpp">T</code> and <code class="sourceCode cpp">UTypes<span class="op">...</span></code> expands to <code class="sourceCode cpp">U</code>) <code class="sourceCode cpp">is_convertible_v<span class="op">&lt;</span>tuple<span class="op">&lt;</span>U<span class="op">&gt;</span>, T<span class="op">&gt;</span></code>, <code class="sourceCode cpp">is_constructible_v<span class="op">&lt;</span>T, tuple<span class="op">&lt;</span>U<span class="op">&gt;&gt;</span></code>, and <code class="sourceCode cpp">is_same_v<span class="op">&lt;</span>T, U<span class="op">&gt;</span></code> are all <code class="sourceCode cpp"><span class="kw">false</span></code>.</li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">22</a></span> <em>Effects:</em> For all <em>i</em>, initializes the <em>i</em><sup>th</sup> element of <code class="sourceCode cpp"><span class="op">*</span><span class="kw">this</span></code> with <code class="sourceCode cpp">std<span class="op">::</span>forward<span class="op">&lt;</span>U<em><sub>i</sub></em><span class="op">&gt;(</span>get<span class="op">&lt;</span><em>i</em><span class="op">&gt;(</span>u<span class="op">))</span></code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">23</a></span> <em>Remarks:</em> The expression inside <code class="sourceCode cpp"><span class="kw">explicit</span></code> is equivalent to: <code class="sourceCode cpp"><span class="op">!</span>conjunction_v<span class="op">&lt;</span>is_convertible<span class="op">&lt;</span>UTypes, Types<span class="op">&gt;...&gt;</span></code>. <span class="diffins">This constructor is defined as deleted if <code class="sourceCode cpp"><span class="op">(</span>reference_constructs_from_temporary_v<span class="op">&lt;</span>Types, UTypes<span class="op">&amp;&amp;&gt;</span> <span class="op">||</span> <span class="op">...)</span></code> is <code class="sourceCode cpp"><span class="kw">true</span></code>.</span></p>
</blockquote>
<div class="sourceCode" id="cb16"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb16-1"><a href="#cb16-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> U1, <span class="kw">class</span> U2<span class="op">&gt;</span> <span class="kw">constexpr</span> <span class="kw">explicit</span><span class="op">(</span><em>see below</em><span class="op">)</span> tuple<span class="op">(</span><span class="kw">const</span> pair<span class="op">&lt;</span>U1, U2<span class="op">&gt;&amp;</span> u<span class="op">)</span>;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">24</a></span> <em>Constraints:</em></p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">(24.1)</a></span> <code class="sourceCode cpp"><span class="kw">sizeof</span><span class="op">...(</span>Types<span class="op">)</span></code> is 2,</li>
<li><span class="marginalizedparent"><a class="marginalized">(24.2)</a></span> <code class="sourceCode cpp">is_constructible_v<span class="op">&lt;</span>T<sub>0</sub>, <span class="kw">const</span> U1<span class="op">&amp;&gt;</span></code> is <code class="sourceCode cpp"><span class="kw">true</span></code>, and</li>
<li><span class="marginalizedparent"><a class="marginalized">(24.3)</a></span> <code class="sourceCode cpp">is_constructible_v<span class="op">&lt;</span>T<sub>1</sub>, <span class="kw">const</span> U2<span class="op">&amp;&gt;</span></code> is <code class="sourceCode cpp"><span class="kw">true</span></code>.</li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">25</a></span> <em>Effects:</em> Initializes the first element with <code class="sourceCode cpp">u<span class="op">.</span>first</code> and the second element with <code class="sourceCode cpp">u<span class="op">.</span>second</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">26</a></span> <em>Remarks:</em> The expression inside <code class="sourceCode cpp"><span class="kw">explicit</span></code> is equivalent to: <code class="sourceCode cpp"><span class="op">!</span>is_convertible_v<span class="op">&lt;</span><span class="kw">const</span> U1<span class="op">&amp;</span>, T<sub>0</sub><span class="op">&gt;</span> <span class="op">||</span> <span class="op">!</span>is_convertible_v<span class="op">&lt;</span><span class="kw">const</span> U2<span class="op">&amp;</span>, T<sub>1</sub><span class="op">&gt;</span></code>. <span class="diffins">This constructor is defined as deleted if <code class="sourceCode cpp">reference_constructs_from_temporary_v<span class="op">&lt;</span>T<sub>0</sub>, <span class="kw">const</span> U1<span class="op">&amp;&gt;</span></code> is <code class="sourceCode cpp"><span class="kw">true</span></code> or <code class="sourceCode cpp">reference_constructs_from_temporary_v<span class="op">&lt;</span>T<sub>1</sub>, <span class="kw">const</span> U2<span class="op">&amp;&gt;</span></code> is <code class="sourceCode cpp"><span class="kw">true</span></code>.</span></p>
</blockquote>
<div class="sourceCode" id="cb17"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb17-1"><a href="#cb17-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> U1, <span class="kw">class</span> U2<span class="op">&gt;</span> <span class="kw">constexpr</span> <span class="kw">explicit</span><span class="op">(</span><em>see below</em><span class="op">)</span> tuple<span class="op">(</span>pair<span class="op">&lt;</span>U1, U2<span class="op">&gt;&amp;&amp;</span> u<span class="op">)</span>;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">27</a></span> <em>Constraints:</em></p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">(27.1)</a></span> <code class="sourceCode cpp"><span class="kw">sizeof</span><span class="op">...(</span>Types<span class="op">)</span></code> is 2,</li>
<li><span class="marginalizedparent"><a class="marginalized">(27.2)</a></span> <code class="sourceCode cpp">is_constructible_v<span class="op">&lt;</span>T<sub>0</sub>, U1<span class="op">&gt;</span></code> is <code class="sourceCode cpp"><span class="kw">true</span></code>, and</li>
<li><span class="marginalizedparent"><a class="marginalized">(27.3)</a></span> <code class="sourceCode cpp">is_constructible_v<span class="op">&lt;</span>T<sub>1</sub>, U2<span class="op">&gt;</span></code> is <code class="sourceCode cpp"><span class="kw">true</span></code>.</li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">28</a></span> <em>Effects:</em> Initializes the first element with <code class="sourceCode cpp">std<span class="op">::</span>forward<span class="op">&lt;</span>U1<span class="op">&gt;(</span>u<span class="op">.</span>first<span class="op">)</span></code> and the second element with <code class="sourceCode cpp">std<span class="op">::</span>forward<span class="op">&lt;</span>U2<span class="op">&gt;(</span>u<span class="op">.</span>second<span class="op">)</span></code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">29</a></span> <em>Remarks:</em> The expression inside <code class="sourceCode cpp"><span class="kw">explicit</span></code> is equivalent to: <code class="sourceCode cpp"><span class="op">!</span>is_convertible_v<span class="op">&lt;</span>U1, T<sub>0</sub><span class="op">&gt;</span> <span class="op">||</span> <span class="op">!</span>is_convertible_v<span class="op">&lt;</span>U2, T<sub>1</sub><span class="op">&gt;</span></code>. <span class="diffins">This constructor is defined as deleted if <code class="sourceCode cpp">reference_constructs_from_temporary_v<span class="op">&lt;</span>T<sub>0</sub>, U1<span class="op">&amp;&amp;&gt;</span></code> is <code class="sourceCode cpp"><span class="kw">true</span></code> or <code class="sourceCode cpp">reference_constructs_from_temporary_v<span class="op">&lt;</span>T<sub>1</sub>, U2<span class="op">&amp;&amp;&gt;</span></code> is <code class="sourceCode cpp"><span class="kw">true</span></code>.</span></p>
</blockquote>
</div>
</blockquote>
<ol start="6" type="1">
<li>Edit <span>20.14.4 <a href="https://wg21.link/func.require">[func.require]</a></span> p2 as indicated:</li>
</ol>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span> Define <code class="sourceCode cpp">INVOKE<span class="op">&lt;</span>R<span class="op">&gt;(</span>f, t1, t2, <span class="op">...</span> , tN <span class="op">)</span></code> as <code class="sourceCode cpp"><span class="kw">static_cast</span><span class="op">&lt;</span><span class="dt">void</span><span class="op">&gt;(</span>INVOKE<span class="op">(</span>f, t1, t2, <span class="op">...</span> , tN <span class="op">))</span></code> if R is <em>cv</em> <code class="sourceCode cpp"><span class="dt">void</span></code>, otherwise <code class="sourceCode cpp">INVOKE<span class="op">(</span>f, t1, t2, <span class="op">...</span> , tN <span class="op">)</span></code> implicitly converted to <code class="sourceCode cpp">R</code>. <span class="diffins">If <code class="sourceCode cpp">reference_converts_from_temporary_v<span class="op">&lt;</span>R, <span class="kw">decltype</span><span class="op">(</span>INVOKE<span class="op">(</span>f, t1, t2, <span class="op">...</span> , tN<span class="op">))&gt;</span></code> is <code class="sourceCode cpp"><span class="kw">true</span></code>, <code class="sourceCode cpp">INVOKE<span class="op">&lt;</span>R<span class="op">&gt;(</span>f, t1, t2, <span class="op">...</span> , tN <span class="op">)</span></code> is ill-formed.</span></p>
</blockquote>
</div>
<h1 data-number="8" style="border-bottom:1px solid #cccccc" id="bibliography"><span class="header-section-number">8</span> References<a href="#bibliography" class="self-link"></a></h1>
<div id="refs" class="references hanging-indent" role="doc-bibliography">
<div id="ref-CWG1696">
<p>[CWG1696] Richard Smith. 2013-05-31. Temporary lifetime and non-static data member initializers. <br />
<a href="https://wg21.link/cwg1696">https://wg21.link/cwg1696</a></p>
</div>
<div id="ref-gcc-pr95153">
<p>[gcc-pr95153] Alisdair Meredith. 2020. Bug 95153 - Arrays of <code class="sourceCode cpp"><span class="kw">const</span> <span class="dt">void</span> <span class="op">*</span></code> should not be copyable in C++20. <br />
<a href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95153">https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95153</a></p>
</div>
<div id="ref-LWG2813">
<p>[LWG2813] Brian Bi. std::function should not return dangling references. <br />
<a href="https://wg21.link/lwg2813">https://wg21.link/lwg2813</a></p>
</div>
<div id="ref-LWG3440">
<p>[LWG3440] Ville Voutilainen. Aggregate-paren-init breaks direct-initializing a tuple or optional from {aggregate-member-value}. <br />
<a href="https://wg21.link/lwg3440">https://wg21.link/lwg3440</a></p>
</div>
<div id="ref-N4868">
<p>[N4868] Richard Smith. 2020-10-18. Working Draft, Standard for Programming Language C++. <br />
<a href="https://wg21.link/n4868">https://wg21.link/n4868</a></p>
</div>
<div id="ref-P0288R7">
<p>[P0288R7] Ryan McDougall, Matt Calabrese. 2020-09-03. any_invocable. <br />
<a href="https://wg21.link/p0288r7">https://wg21.link/p0288r7</a></p>
</div>
<div id="ref-P0792R5">
<p>[P0792R5] Vittorio Romeo. 2019-10-06. function_ref: a non-owning reference to a Callable. <br />
<a href="https://wg21.link/p0792r5">https://wg21.link/p0792r5</a></p>
</div>
<div id="ref-P0932R1">
<p>[P0932R1] Aaryaman Sagar. 2018-02-07. Tightening the constraints on std::function. <br />
<a href="https://wg21.link/p0932r1">https://wg21.link/p0932r1</a></p>
</div>
<div id="ref-P2136R1">
<p>[P2136R1] Zhihao Yuan. 2020-05-15. invoke_r. <br />
<a href="https://wg21.link/p2136r1">https://wg21.link/p2136r1</a></p>
</div>
</div>
</div>
</div>
</body>
</html>
