<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang xml:lang>
<head>
  <meta charset="utf-8" />
  <meta name="generator" content="mpark/wg21" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
  <meta name="dcterms.date" content="2023-05-12" />
  <title>Nontrivial Relocation via a New *owning reference* Type</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 { } 
code span.al { color: #ff0000; } 
code span.an { } 
code span.at { } 
code span.bn { color: #9f6807; } 
code span.bu { color: #9f6807; } 
code span.cf { color: #00607c; } 
code span.ch { color: #9f6807; } 
code span.cn { } 
code span.co { color: #008000; font-style: italic; } 
code span.cv { color: #008000; font-style: italic; } 
code span.do { color: #008000; } 
code span.dt { color: #00607c; } 
code span.dv { color: #9f6807; } 
code span.er { color: #ff0000; font-weight: bold; } 
code span.ex { } 
code span.fl { color: #9f6807; } 
code span.fu { } 
code span.im { } 
code span.in { color: #008000; } 
code span.kw { color: #00607c; } 
code span.op { color: #af1915; } 
code span.ot { } 
code span.pp { color: #6f4e37; } 
code span.re { } 
code span.sc { color: #9f6807; } 
code span.ss { color: #9f6807; } 
code span.st { color: #9f6807; } 
code span.va { } 
code span.vs { color: #9f6807; } 
code span.wa { color: #008000; font-weight: bold; } 
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: 2.5em;
margin-top: -0.2em;
margin-bottom: -0.2em;
}
ol {
padding-left: 2.5em;
}
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;
}

#TOC ul > li:before {
content: none;
}
#TOC > ul {
padding-left: 0;
}

.toc-section-number {
margin-right: 0.5em;
}
:target { background-color: #C9FBC9; }
:target .codeblock { background-color: #C9FBC9; }
:target ul { background-color: #C9FBC9; }
.abbr_ref { float: right; }
.folded_abbr_ref { float: right; }
:target .folded_abbr_ref { display: none; }
:target .unfolded_abbr_ref { float: right; display: inherit; }
.unfolded_abbr_ref { display: none; }
.secnum { display: inline-block; min-width: 35pt; }
.header-section-number { display: inline-block; min-width: 35pt; }
.annexnum { display: block; }
div.sourceLinkParent {
float: right;
}
a.sourceLink {
position: absolute;
opacity: 0;
margin-left: 10pt;
}
a.sourceLink:hover {
opacity: 1;
}
a.itemDeclLink {
position: absolute;
font-size: 75%;
text-align: right;
width: 5em;
opacity: 0;
}
a.itemDeclLink:hover { opacity: 1; }
span.marginalizedparent {
position: relative;
left: -5em;
}
li span.marginalizedparent { left: -7em; }
li ul > li span.marginalizedparent { left: -9em; }
li ul > li ul > li span.marginalizedparent { left: -11em; }
li ul > li ul > li ul > li span.marginalizedparent { left: -13em; }
div.footnoteNumberParent {
position: relative;
left: -4.7em;
}
a.marginalized {
position: absolute;
font-size: 75%;
text-align: right;
width: 5em;
}
a.enumerated_item_num {
position: relative;
left: -3.5em;
display: inline-block;
margin-right: -3em;
text-align: right;
width: 3em;
}
div.para { margin-bottom: 0.6em; margin-top: 0.6em; text-align: justify; }
div.section { text-align: justify; }
div.sentence { display: inline; }
span.indexparent {
display: inline;
position: relative;
float: right;
right: -1em;
}
a.index {
position: absolute;
display: none;
}
a.index:before { content: "⟵"; }

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

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

code.sourceCode > span { display: inline; }
</style>
  <link href="data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAVoJEAN6CRADegkQAWIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wCCRAAAgkQAAIJEAACCRAAsgkQAvoJEAP+CRAD/gkQA/4JEAP+CRADAgkQALoJEAACCRAAAgkQAAP///wD///8AgkQAAIJEABSCRACSgkQA/IJEAP99PQD/dzMA/3czAP99PQD/gkQA/4JEAPyCRACUgkQAFIJEAAD///8A////AHw+AFiBQwDqgkQA/4BBAP9/PxP/uZd6/9rJtf/bybX/upd7/39AFP+AQQD/gkQA/4FDAOqAQgBc////AP///wDKklv4jlEa/3o7AP+PWC//8+3o///////////////////////z7un/kFox/35AAP+GRwD/mVYA+v///wD///8A0Zpk+NmibP+0d0T/8evj///////+/fv/1sKz/9bCs//9/fr//////+/m2/+NRwL/nloA/5xYAPj///8A////ANKaZPjRmGH/5cKh////////////k149/3UwAP91MQD/lmQ//86rhv+USg3/m1YA/5hSAP+bVgD4////AP///wDSmmT4zpJY/+/bx///////8+TV/8mLT/+TVx//gkIA/5lVAP+VTAD/x6B//7aEVv/JpH7/s39J+P///wD///8A0ppk+M6SWP/u2sf///////Pj1f/Nj1T/2KFs/8mOUv+eWhD/lEsA/8aee/+0glT/x6F7/7J8Rvj///8A////ANKaZPjRmGH/48Cf///////+/v7/2qt//82PVP/OkFX/37KJ/86siv+USg7/mVQA/5hRAP+bVgD4////AP///wDSmmT40ppk/9CVXP/69O////////7+/v/x4M//8d/P//7+/f//////9u7n/6tnJf+XUgD/nFgA+P///wD///8A0ppk+NKaZP/RmWL/1qNy//r07///////////////////////+vXw/9akdP/Wnmn/y5FY/6JfFvj///8A////ANKaZFTSmmTo0ppk/9GYYv/Ql1//5cWm//Hg0P/x4ND/5cWm/9GXYP/RmGH/0ppk/9KaZOjVnmpY////AP///wDSmmQA0ppkEtKaZI7SmmT60ppk/9CWX//OkVb/zpFW/9CWX//SmmT/0ppk/NKaZJDSmmQS0ppkAP///wD///8A0ppkANKaZADSmmQA0ppkKtKaZLrSmmT/0ppk/9KaZP/SmmT/0ppkvNKaZCrSmmQA0ppkANKaZAD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkUtKaZNzSmmTc0ppkVNKaZADSmmQA0ppkANKaZADSmmQA////AP5/AAD4HwAA4AcAAMADAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAMADAADgBwAA+B8AAP5/AAAoAAAAIAAAAEAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wCCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAAyCRACMgkQA6oJEAOqCRACQgkQAEIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wD///8A////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRABigkQA5oJEAP+CRAD/gkQA/4JEAP+CRADqgkQAZoJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAAD///8A////AP///wD///8AgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAA4gkQAwoJEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQAxIJEADyCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAP///wD///8A////AP///wCCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAWgkQAmIJEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAJyCRAAYgkQAAIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wD///8A////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAdIJEAPCCRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAPSCRAB4gkQAAIJEAACCRAAAgkQAAIJEAAD///8A////AP///wD///8AgkQAAIJEAACCRAAAgkQASoJEANKCRAD/gkQA/4JEAP+CRAD/g0YA/39AAP9zLgD/bSQA/2shAP9rIQD/bSQA/3MuAP9/PwD/g0YA/4JEAP+CRAD/gkQA/4JEAP+CRADUgkQAToJEAACCRAAAgkQAAP///wD///8A////AP///wB+PwAAgkUAIoJEAKiCRAD/gkQA/4JEAP+CRAD/hEcA/4BBAP9sIwD/dTAA/5RfKv+viF7/vp56/76ee/+wiF7/lWAr/3YxAP9sIwD/f0AA/4RHAP+CRAD/gkQA/4JEAP+CRAD/gkQArIJEACaBQwAA////AP///wD///8A////AIBCAEBzNAD6f0EA/4NFAP+CRAD/gkQA/4VIAP92MwD/bSUA/6N1Tv/ezsL/////////////////////////////////38/D/6V3Uv9uJgD/dTEA/4VJAP+CRAD/gkQA/4JEAP+BQwD/fUAA/4FDAEj///8A////AP///wD///8AzJRd5qBlKf91NgD/dDUA/4JEAP+FSQD/cy4A/3YyAP/PuKP//////////////////////////////////////////////////////9K7qP94NQD/ciwA/4VJAP+CRAD/fkEA/35BAP+LSwD/mlYA6v///wD///8A////AP///wDdpnL/4qx3/8KJUv+PUhf/cTMA/3AsAP90LgD/4dK+/////////////////////////////////////////////////////////////////+TYxf91MAD/dTIA/31CAP+GRwD/llQA/6FcAP+gWwD8////AP///wD///8A////ANGZY/LSm2X/4ap3/92mcP+wdT3/byQA/8mwj////////////////////////////////////////////////////////////////////////////+LYxv9zLgP/jUoA/59bAP+hXAD/nFgA/5xYAPL///8A////AP///wD///8A0ppk8tKaZP/RmWL/1p9q/9ubXv/XqXj////////////////////////////7+fD/vZyG/6BxS/+gcUr/vJuE//r37f//////////////////////3MOr/5dQBf+dVQD/nVkA/5xYAP+cWAD/nFgA8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/SmWP/yohJ//jo2P//////////////////////4NTG/4JDFf9lGAD/bSQA/20kAP9kGAD/fz8S/+Xb0f//////5NG9/6txN/+LOgD/m1QA/51aAP+cWAD/m1cA/5xYAP+cWADy////AP///wD///8A////ANKaZPLSmmT/0ppk/8+TWf/Unmv//v37//////////////////////+TWRr/VwsA/35AAP+ERgD/g0UA/4JGAP9lHgD/kFga/8KXX/+TRwD/jT4A/49CAP+VTQD/n10A/5xYAP+OQQD/lk4A/55cAPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/y4tO/92yiP//////////////////////8NnE/8eCQP+rcTT/ez0A/3IyAP98PgD/gEMA/5FSAP+USwD/jj8A/5lUAP+JNwD/yqV2/694Mf+HNQD/jkAA/82rf/+laBj/jT4A8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/LiUr/4byY///////////////////////gupX/0I5P/+Wuev/Lklz/l1sj/308AP+QSwD/ol0A/59aAP+aVQD/k0oA/8yoh///////+fXv/6pwO//Lp3v///////Pr4f+oay7y////AP///wD///8A////ANKaZPLSmmT/0ppk/8uJSv/hvJj//////////////////////+G7l//Jhkb/0ppk/96nc//fqXX/x4xO/6dkFP+QSQD/llEA/5xXAP+USgD/yaOA///////38uv/qG05/8ijdv//////8efb/6ZpLPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/zIxO/9yxh///////////////////////7dbA/8iEQf/Sm2X/0Zlj/9ScZv/eqHf/2KJv/7yAQf+XTgD/iToA/5lSAP+JNgD/yKFv/611LP+HNQD/jT8A/8qmeP+kZRT/jT4A8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/Pk1n/1J5q//78+//////////////////+/fv/1aFv/8iEQv/Tm2b/0ppl/9GZY//Wn2z/1pZc/9eldf/Bl2b/kUcA/4w9AP+OQAD/lUwA/59eAP+cWQD/jT8A/5ZOAP+eXADy////AP///wD///8A////ANKaZPLSmmT/0ppk/9KZY//KiEn/8d/P///////////////////////47+f/05tm/8iCP//KiEj/yohJ/8eCP//RmGH//vfy///////n1sP/rXQ7/4k4AP+TTAD/nVoA/5xYAP+cVwD/nFgA/5xYAPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/0ptl/8uLTf/aq37////////////////////////////+/fz/6c2y/961jv/etY7/6Myx//78+v//////////////////////3MWv/5xXD/+ORAD/mFQA/51ZAP+cWAD/nFgA8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/SmmT/0ppk/8mFRP/s1b//////////////////////////////////////////////////////////////////////////////+PD/0JFU/7NzMv+WUQD/kUsA/5tXAP+dWQDy////AP///wD///8A////ANKaZP/SmmT/0ppk/9KaZP/Sm2X/z5NZ/8yMT//z5NX/////////////////////////////////////////////////////////////////9Ofa/8yNUP/UmGH/36p5/8yTWv+qaSD/kksA/5ROAPz///8A////AP///wD///8A0ppk5NKaZP/SmmT/0ppk/9KaZP/TnGf/zY9T/82OUv/t1sD//////////////////////////////////////////////////////+7Yw//OkFX/zI5R/9OcZ//SmmP/26V0/9ymdf/BhUf/ol8R6P///wD///8A////AP///wDSmmQ80ppk9tKaZP/SmmT/0ppk/9KaZP/TnGj/zpFW/8qJSv/dson/8uHS//////////////////////////////////Lj0//etIv/y4lL/86QVf/TnGj/0ppk/9KaZP/RmWP/05xn/9ymdfjUnWdC////AP///wD///8A////ANKaZADSmmQc0ppkotKaZP/SmmT/0ppk/9KaZP/Tm2b/0Zli/8qJSf/NjlH/16Z3/+G8mP/myKr/5siq/+G8mP/Xp3f/zY5S/8qISf/RmGH/05tm/9KaZP/SmmT/0ppk/9KaZP/SmmSm0pljINWdaQD///8A////AP///wD///8A0ppkANKaZADSmmQA0ppkQtKaZMrSmmT/0ppk/9KaZP/SmmT/0ptl/9GYYf/Nj1P/y4lL/8qISP/KiEj/y4lK/82PU//RmGH/0ptl/9KaZP/SmmT/0ppk/9KaZP/SmmTO0ppkRtKaZADSmmQA0ppkAP///wD///8A////AP///wDSmmQA0ppkANKaZADSmmQA0ppkANKaZGzSmmTu0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmTw0ppkcNKaZADSmmQA0ppkANKaZADSmmQA////AP///wD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZBLSmmSQ0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppklNKaZBTSmmQA0ppkANKaZADSmmQA0ppkANKaZAD///8A////AP///wD///8A0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQy0ppkutKaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppkvtKaZDbSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkAP///wD///8A////AP///wDSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkXNKaZODSmmT/0ppk/9KaZP/SmmT/0ppk5NKaZGDSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA////AP///wD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkBtKaZIbSmmTo0ppk6tKaZIrSmmQK0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZAD///8A////AP/8P///+B///+AH//+AAf//AAD//AAAP/AAAA/gAAAHwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA+AAAAfwAAAP/AAAP/8AAP//gAH//+AH///4H////D//" rel="icon" />
  
  <!--[if lt IE 9]>
    <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
  <![endif]-->
</head>
<body>
<div class="wrapper">
<header id="title-block-header">
<h1 class="title" style="text-align:center">Nontrivial Relocation via a
New <em>owning reference</em> Type</h1>
<table style="border:none;float:right">
  <tr>
    <td>Document #:</td>
    <td>P2839R0</td>
  </tr>
  <tr>
    <td>Date:</td>
    <td>2023-05-12</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>
      EWGI<br>
    </td>
  </tr>
  <tr>
    <td style="vertical-align:top">Reply-to:</td>
    <td>
      Brian Bi<br>&lt;<a href="mailto:bbi10@bloomberg.net" class="email">bbi10@bloomberg.net</a>&gt;<br>
      Joshua Berne<br>&lt;<a href="mailto:jberne4@bloomberg.net" class="email">jberne4@bloomberg.net</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" id="toc-abstract"><span class="toc-section-number">1</span> Abstract</a></li>
<li><a href="#introduction" id="toc-introduction"><span class="toc-section-number">2</span> Introduction</a></li>
<li><a href="#structure-of-this-proposal" id="toc-structure-of-this-proposal"><span class="toc-section-number">3</span> Structure of this proposal</a></li>
<li><a href="#part-i-owning-references-and-defaulted-relocation-constructors" id="toc-part-i-owning-references-and-defaulted-relocation-constructors"><span class="toc-section-number">4</span> Part I: Owning references and
defaulted relocation constructors</a>
<ul>
<li><a href="#summary" id="toc-summary"><span class="toc-section-number">4.1</span> Summary</a></li>
<li><a href="#defaulted-relocation-constructors" id="toc-defaulted-relocation-constructors"><span class="toc-section-number">4.2</span> Defaulted relocation
constructors</a></li>
<li><a href="#conversions" id="toc-conversions"><span class="toc-section-number">4.3</span> Conversions</a></li>
<li><a href="#relocation-of-automatic-variables" id="toc-relocation-of-automatic-variables"><span class="toc-section-number">4.4</span> Relocation of automatic
variables</a></li>
<li><a href="#the-reloc-operator" id="toc-the-reloc-operator"><span class="toc-section-number">4.5</span> The
<code class="sourceCode default">reloc</code> operator</a></li>
<li><a href="#reference-collapsing-and-perfect-forwarding" id="toc-reference-collapsing-and-perfect-forwarding"><span class="toc-section-number">4.6</span> Reference collapsing and perfect
forwarding</a></li>
<li><a href="#restrictions-on-owning-references" id="toc-restrictions-on-owning-references"><span class="toc-section-number">4.7</span> Restrictions on owning
references</a></li>
<li><a href="#further-examples-of-disengagement-and-control-flow" id="toc-further-examples-of-disengagement-and-control-flow"><span class="toc-section-number">4.8</span> Further examples of disengagement
and control flow</a></li>
<li><a href="#miscellaneous" id="toc-miscellaneous"><span class="toc-section-number">4.9</span> Miscellaneous</a>
<ul>
<li><a href="#implicit-relocation-by-return-statements" id="toc-implicit-relocation-by-return-statements"><span class="toc-section-number">4.9.1</span> Implicit relocation by
<code class="sourceCode default">return</code> statements</a></li>
<li><a href="#pseudo-destructor-call-on-owning-reference" id="toc-pseudo-destructor-call-on-owning-reference"><span class="toc-section-number">4.9.2</span> Pseudo-destructor call on owning
reference</a></li>
<li><a href="#the-stdforce_relocate-function" id="toc-the-stdforce_relocate-function"><span class="toc-section-number">4.9.3</span> The
<code class="sourceCode default">std::force_relocate</code>
function</a></li>
<li><a href="#the-stdrelocate_ptr-smart-pointer" id="toc-the-stdrelocate_ptr-smart-pointer"><span class="toc-section-number">4.9.4</span> The
<code class="sourceCode default">std::relocate_ptr</code> smart
pointer</a></li>
<li><a href="#the-stddisengage-function" id="toc-the-stddisengage-function"><span class="toc-section-number">4.9.5</span> The
<code class="sourceCode default">std::disengage</code> function</a></li>
</ul></li>
</ul></li>
<li><a href="#part-ii-user-provided-relocation-constructors" id="toc-part-ii-user-provided-relocation-constructors"><span class="toc-section-number">5</span> Part II: User-provided relocation
constructors</a>
<ul>
<li><a href="#example-relocate-only-small-vector" id="toc-example-relocate-only-small-vector"><span class="toc-section-number">5.1</span> Example: Relocate-only small
vector</a></li>
</ul></li>
<li><a href="#part-iii-subordinate-references-and-delayed-initialization" id="toc-part-iii-subordinate-references-and-delayed-initialization"><span class="toc-section-number">6</span> Part III: Subordinate references and
delayed initialization</a>
<ul>
<li><a href="#motivation-for-delayed-initialization" id="toc-motivation-for-delayed-initialization"><span class="toc-section-number">6.1</span> Motivation for delayed
initialization</a></li>
<li><a href="#subordinate-references" id="toc-subordinate-references"><span class="toc-section-number">6.2</span> Subordinate references</a></li>
<li><a href="#explicit-owning-reference-to-self-for-destructors" id="toc-explicit-owning-reference-to-self-for-destructors"><span class="toc-section-number">6.3</span> Explicit owning reference to self
for destructors</a></li>
</ul></li>
<li><a href="#comparison-with-other-relocation-proposals" id="toc-comparison-with-other-relocation-proposals"><span class="toc-section-number">7</span> Comparison with other relocation
proposals</a>
<ul>
<li><a href="#d2785" id="toc-d2785"><span class="toc-section-number">7.1</span> D2785</a></li>
<li><a href="#n4158" id="toc-n4158"><span class="toc-section-number">7.2</span> N4158</a></li>
<li><a href="#p0023" id="toc-p0023"><span class="toc-section-number">7.3</span> P0023</a></li>
<li><a href="#p1144r7-and-p2786r0" id="toc-p1144r7-and-p2786r0"><span class="toc-section-number">7.4</span> P1144R7 and P2786R0</a></li>
<li><a href="#p1029r3" id="toc-p1029r3"><span class="toc-section-number">7.5</span> P1029R3</a></li>
</ul></li>
<li><a href="#appendix-a-potentially-breaking-changes" id="toc-appendix-a-potentially-breaking-changes"><span class="toc-section-number">8</span> Appendix A: Potentially breaking
changes</a></li>
<li><a href="#appendix-b-alternative-syntaxes-for-forwarding-references" id="toc-appendix-b-alternative-syntaxes-for-forwarding-references"><span class="toc-section-number">9</span> Appendix B: Alternative syntaxes for
forwarding references</a>
<ul>
<li><a href="#t-syntax" id="toc-t-syntax"><span class="toc-section-number">9.1</span>
<code class="sourceCode default">T~</code> syntax</a></li>
<li><a href="#t-syntax-1" id="toc-t-syntax-1"><span class="toc-section-number">9.2</span>
<code class="sourceCode default">T&amp;&amp;</code> syntax</a>
<ul>
<li><a href="#subapproach-1-changing-the-reference-collapsing-rules" id="toc-subapproach-1-changing-the-reference-collapsing-rules"><span class="toc-section-number">9.2.1</span> Subapproach 1: Changing the
reference collapsing rules</a></li>
<li><a href="#subapproach-2-changing-the-reference-collapsing-rules-but-only-for-forwarding-references" id="toc-subapproach-2-changing-the-reference-collapsing-rules-but-only-for-forwarding-references"><span class="toc-section-number">9.2.2</span> Subapproach 2: Changing the
reference collapsing rules but only for forwarding references</a></li>
<li><a href="#subapproach-3-making-reference-collapsing-ill-formed-outside-forwarding-references" id="toc-subapproach-3-making-reference-collapsing-ill-formed-outside-forwarding-references"><span class="toc-section-number">9.2.3</span> Subapproach 3: Making reference
collapsing ill formed outside forwarding references</a></li>
<li><a href="#subapproach-4-abominable-types" id="toc-subapproach-4-abominable-types"><span class="toc-section-number">9.2.4</span> Subapproach 4: Abominable
types</a></li>
</ul></li>
<li><a href="#a-completely-different-syntax" id="toc-a-completely-different-syntax"><span class="toc-section-number">9.3</span> A completely different
syntax</a></li>
<li><a href="#conclusion-on-forwarding-reference-syntax" id="toc-conclusion-on-forwarding-reference-syntax"><span class="toc-section-number">9.4</span> Conclusion on forwarding reference
syntax</a></li>
</ul></li>
<li><a href="#appendix-c-alternative-names" id="toc-appendix-c-alternative-names"><span class="toc-section-number">10</span> Appendix C: Alternative
names</a></li>
<li><a href="#bibliography" id="toc-bibliography"><span class="toc-section-number">11</span> References</a></li>
</ul>
</div>
<h1 data-number="1" id="abstract"><span class="header-section-number">1</span> Abstract<a href="#abstract" class="self-link"></a></h1>
<p>A new type of reference, known as the <em>owning reference</em>, is
proposed with the spelling <code class="sourceCode default">T~</code>.
An owning reference is responsible for destroying the object it refers
to and may be used to initialize the parameter of a constructor of the
form <code class="sourceCode default">T::T(T~)</code>, which is known as
a <em>relocation constructor</em> and performs the responsibilities of
both a constructor and destructor. An owning reference that has been
moved from is <em>disengaged</em>, does not refer to an object, and is
ill formed when named by an expression. Further extensions that build on
top of the basic concept of owning references are proposed to facilitate
the implementation of user-defined relocation constructors.</p>
<h1 data-number="2" id="introduction"><span class="header-section-number">2</span> Introduction<a href="#introduction" class="self-link"></a></h1>
<p>Numerous proposals have attempted to introduce the ability to tie
together the construction of one object with the destruction of a source
object, migrating the value of that source object in the process. We
discuss some such proposals in Section 7. Normal C++ move-initialization
accomplishes migration of an object’s value but fails to address the
source object’s lifetime, thus requiring that the source object support
being in a <em>valueless</em> state (i.e., a state having a logically
valid value that must be accounted for by any function having a wide
contract, while semantically representing the absence of a value).</p>
<p>When an object’s lifetime can also be ended as part of moving its
value to a new object, performance can be improved in various ways:</p>
<ul>
<li>No writes need to be done to the source object to indicate that it
is now valueless.</li>
<li>For a type that requires a new allocation to be in a valueless
state, such as some list implementations that allocate a sentinel node,
this allocation can be completely skipped.</li>
<li>No extra checks need to be done in a destructor to <em>clean up</em>
an object that is in the valueless state.</li>
</ul>
<p>On top of that, although not <em>all</em> move-initializations
immediately precede the destruction of the source object, many of them
do:</p>
<ul>
<li>Rearranging objects within a
<code class="sourceCode default">std::vector</code> often involves
chains of move-construct and destroy operations.</li>
<li>Passing a function argument to a by-value parameter when the source
object is a temporary generally involves nothing further happening with
that temporary object prior to its destruction at the end of the
complete enclosing statement.</li>
</ul>
<p>Surprisingly, types that do not include references to themselves tend
to not only be relocatable, but to be relocatable in a trivial fashion;
i.e., the relocation can be accomplished by simply invoking
<code class="sourceCode default">memcpy</code> on the source object and
then not invoking that object’s destructor but nonetheless ending its
lifetime. This case is so prevalent and the performance benefits when
taking advantage of it within containers is so significant that numerous
historical proposals have been written to add <em>just</em> trivial
relocation to the library or language: <span class="citation" data-cites="P1029R1">[<a href="#ref-P1029R1" role="doc-biblioref">P1029R1</a>]</span>, <span class="citation" data-cites="P1144R6">[<a href="#ref-P1144R6" role="doc-biblioref">P1144R6</a>]</span>, and <span class="citation" data-cites="P2786R0">[<a href="#ref-P2786R0" role="doc-biblioref">P2786R0</a>]</span>.</p>
<p>A common initial response to these proposals for trivial relocation
is confusion about proposing a trivial version of an operation where we
do not have a nontrivial option. Certainly no other fundamental C++
operation is supported only when trivial and provides no mechanism to
insert a user-defined version of that operation. This proposal aims to
provide the complete context in which to understand how trivial
relocation could fit into a larger picture. In particular, should a
trivial relocation proposal such as <span class="citation" data-cites="P2786R0">[<a href="#ref-P2786R0" role="doc-biblioref">P2786R0</a>]</span> move forward, it would be
completely compatible with extending to arbitrary user-defined
relocation through the owning references that we propose here.</p>
<p>By expressing relocation through owning references, rather than
simply providing library functions that allow such relocation, we also
extend the ability to leverage relocation in more places as well as to
safely prevent one of the most common issues with move operations, use
after move.</p>
<h1 data-number="3" id="structure-of-this-proposal"><span class="header-section-number">3</span> Structure of this proposal<a href="#structure-of-this-proposal" class="self-link"></a></h1>
<p>Our proposal is layered in three parts, with each part dependent on
only the previous parts. Later parts could easily be delayed for future
Standards while reaping a subset of the benefits and expressivity with a
smaller initial feature.</p>
<p>Part I introduces owning references and the core language rules
governing their behavior that are needed to support defaulted relocation
constructors, which the authors believe will suffice for the vast
majority of use cases that can benefit from nontrivial relocation.</p>
<p>Part II is a minimal extension to enable users to write their own
relocation constructors. A new syntax is proposed to allow the compiler
to track which subobjects have been relocated from within the
<em>ctor-initializer</em> of a user-defined relocation constructor.</p>
<p>Part III builds on top of Part II to provide further usability
benefits in the implementation of relocation constructors and to enable
destructors to relocate subobjects.</p>
<p>Appendix A discusses extensions that depend only on Part I but are
not included in any of the three main parts because of their potential
impact upon existing code.</p>
<h1 data-number="4" id="part-i-owning-references-and-defaulted-relocation-constructors"><span class="header-section-number">4</span> Part I: Owning references and
defaulted relocation constructors<a href="#part-i-owning-references-and-defaulted-relocation-constructors" class="self-link"></a></h1>
<h2 data-number="4.1" id="summary"><span class="header-section-number">4.1</span> Summary<a href="#summary" class="self-link"></a></h2>
<p>For every object type <code class="sourceCode default">T</code>, we
propose the introduction of a type called <em>owning reference to
<code class="sourceCode default">T</code></em>, which is denoted by
<code class="sourceCode default">T~</code>. An owning reference binds
only to a value category known as the <em>rlvalue</em>. An rlvalue
denotes an object that can be relocated from, just as an xvalue denotes
an object that can be moved from. (See Appendix C for a discussion of
alternative names.)</p>
<p>A value of owning reference type may be either “engaged” or
“disengaged.” An engaged owning reference owns an object: When the
owning reference’s lifetime ends, the object it owns is destroyed. (If
the owning reference is a function parameter, the implicit destructor
call at the end of the reference’s lifetime is performed in callee
context because the caller cannot know whether the callee has disengaged
its owning reference parameter.) Whether a particular owning reference
is engaged or disengaged at a particular program point is always known
statically according to the rules that we will describe later in this
section, and no runtime flags need to be maintained to track that
status.</p>
<p>The name of a variable of type
<code class="sourceCode default">T~</code> is an lvalue, just like the
name of any other reference variable. The lvalue can be converted to an
rlvalue using the <code class="sourceCode default">reloc</code>
operator, which will be discussed in more detail later in this section.
The resulting rlvalue is then engaged, and the original variable is
disengaged. An <em>id-expression</em> that names a disengaged owning
reference is ill formed. If a variable of owning reference type is
disengaged along some paths of control flow, it is implicitly disengaged
at the end of all other branches (i.e., immediately before they rejoin
the branch containing the explicit disengagement), as necessary, to
ensure that it is known to be disengaged when the branches rejoin.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> T <span class="op">{</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> m;</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> g<span class="op">(</span>T<span class="op">&amp;</span> x<span class="op">)</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> f<span class="op">(</span>T<span class="op">~</span> ref<span class="op">)</span> <span class="op">{</span>  <span class="co">// `ref` is engaged and owns some object.</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a>   g<span class="op">(</span>ref<span class="op">)</span>;  <span class="co">// OK; `ref` is an lvalue.</span></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a>   T<span class="op">~</span> ref2 <span class="op">=</span> reloc ref;</span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a>     <span class="co">// `ref` is disengaged; `ref2` is engaged and owns the object.</span></span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a>   g<span class="op">(</span>ref<span class="op">)</span>;   <span class="co">// ill formed; `ref` is disengaged</span></span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a>   <span class="op">++</span>ref<span class="op">.</span>m;  <span class="co">// ditto</span></span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a>   g<span class="op">(</span>ref2<span class="op">)</span>;  <span class="co">// OK</span></span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a>   <span class="cf">if</span> <span class="op">(</span>rand<span class="op">()</span> <span class="op">%</span> <span class="dv">2</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a>     <span class="op">{</span></span>
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a>       T<span class="op">~</span> ref3 <span class="op">=</span> reloc ref2;</span>
<span id="cb1-20"><a href="#cb1-20" aria-hidden="true" tabindex="-1"></a>         <span class="co">// `ref3` is engaged and `ref2` is disengaged.</span></span>
<span id="cb1-21"><a href="#cb1-21" aria-hidden="true" tabindex="-1"></a>       <span class="co">// `ref3`&#39;s lifetime ends here; `ref3.~T()` is called.</span></span>
<span id="cb1-22"><a href="#cb1-22" aria-hidden="true" tabindex="-1"></a>     <span class="op">}</span></span>
<span id="cb1-23"><a href="#cb1-23" aria-hidden="true" tabindex="-1"></a>     g<span class="op">(</span>ref2<span class="op">)</span>;  <span class="co">// error</span></span>
<span id="cb1-24"><a href="#cb1-24" aria-hidden="true" tabindex="-1"></a>   <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb1-25"><a href="#cb1-25" aria-hidden="true" tabindex="-1"></a>     g<span class="op">(</span>ref2<span class="op">)</span>;  <span class="co">// OK</span></span>
<span id="cb1-26"><a href="#cb1-26" aria-hidden="true" tabindex="-1"></a>     <span class="co">// `ref2` is implicitly disengaged here; `ref2.~T()` is called.</span></span>
<span id="cb1-27"><a href="#cb1-27" aria-hidden="true" tabindex="-1"></a>   <span class="op">}</span></span>
<span id="cb1-28"><a href="#cb1-28" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-29"><a href="#cb1-29" aria-hidden="true" tabindex="-1"></a>   g<span class="op">(</span>ref2<span class="op">)</span>;  <span class="co">// error</span></span>
<span id="cb1-30"><a href="#cb1-30" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>See also Section 4.8 below.</p>
<p>A <em>relocation constructor</em> is a nontemplate constructor of a
class <code class="sourceCode default">T</code> whose first parameter is
of type <code class="sourceCode default">T~</code> and all of whose
remaining parameters (if any) have default arguments. From the previous
paragraph, it is apparent that when the constructor’s parameter is
initialized, the parameter has unique ownership of the object it refers
to, and any other rlvalue referring to the same object will have become
disengaged. A relocation constructor, like any other constructor,
creates an object. Because the
<code class="sourceCode default">T~</code> parameter’s lifetime ends at
the closing brace of the constructor, the source object’s lifetime will
end by the time the relocation constructor returns.</p>
<h2 data-number="4.2" id="defaulted-relocation-constructors"><span class="header-section-number">4.2</span> Defaulted relocation
constructors<a href="#defaulted-relocation-constructors" class="self-link"></a></h2>
<p>Certain types will have implicitly declared relocation constructors
that are declared and defined in a similar manner to other special
member functions but are unconditionally
<code class="sourceCode default">noexcept</code>.</p>
<ul>
<li>For trivially relocatable class types, the declared constructor will
be public. See Section 7.4 for discussion on what it means for a class
type to be trivially relocatable.</li>
<li>For class types <code class="sourceCode default">C</code> such that
overload resolution for direct-initializing
<code class="sourceCode default">C</code> from an xvalue of
<code class="sourceCode default">C</code> succeeds and finds a
nondeleted constructor and <code class="sourceCode default">C</code> has
a nondeleted destructor, the declared relocation constructor will have
the more restrictive of access levels of those two functions.</li>
</ul>
<p>Throwing relocation constructors raise difficult specification
problems. When a relocation constructor throws, some of the source
object’s subobjects will have been destroyed already, and destroying the
remaining subobjects might not be safe because the order of destruction
in a relocation constructor is opposite to the usual order of
destruction (i.e., in a destructor). Like throwing move constructors,
throwing relocation constructors are likely to cause problems for
authors of generic code. For these reasons, so we do not propose to
allow throwing relocation constructors at this time.</p>
<p>The behavior of an (implicitly or explicitly) defaulted relocation
constructor is described in the following list.</p>
<ul>
<li>Trivially relocatable types have trivial relocation constructors
that initialize the destination object as if by
<code class="sourceCode default">std::memcpy</code>. As with any other
relocation constructor, a trivial relocation constructor ends the
lifetime of the source object. However, a trivial relocation constructor
does not actually call the destructor for the source object, because the
notion of trivial relocatability is that performing a bitwise copy
followed by forgetting to destroy the old object has the desired
semantics.</li>
<li>Otherwise, if <code class="sourceCode default">C</code> is a class
type described by the second bullet in the previous list:
<ul>
<li><p>If both the constructor selected for direct-initialization of
<code class="sourceCode default">C</code> from an xvalue of
<code class="sourceCode default">C</code> and the destructor of
<code class="sourceCode default">C</code> are defaulted at their first
declaration and if all direct subobjects and virtual base class
subobjects of <code class="sourceCode default">C</code> are relocatable,
the default relocation constructor for
<code class="sourceCode default">C</code> performs a memberwise
relocation of <code class="sourceCode default">C</code>’s direct
subobjects and virtual base class subobjects. (The rationale is that we
can assume that such a class does not need to be patched up after a
memberwise relocation; any such required patchups would have to be
performed by the constructor selected for move-construction, which would
therefore have to be user provided.)</p></li>
<li><p>Otherwise, the relocation constructor for
<code class="sourceCode default">C</code> behaves as if it delegates to
the constructor of <code class="sourceCode default">C</code> that would
be selected to perform a move, which results in the subsequent implicit
destruction of the source object when the
<code class="sourceCode default">T~</code> parameter’s lifetime
ends:</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>T<span class="op">(</span>T<span class="op">~</span> source<span class="op">)</span> <span class="op">:</span> T<span class="op">(</span><span class="kw">static_cast</span><span class="op">&lt;</span>T<span class="op">&amp;&amp;&gt;(</span>source<span class="op">))</span> <span class="op">{}</span></span></code></pre></div></li>
</ul></li>
<li>Otherwise, the relocation constructor is deleted. Note that the
selection of a deleted function by overload resolution causes the
program to be ill formed, but this outcome is undesirable when the
function was implicitly declared or when it was explicitly defaulted in
a templated class in which the author expects that it will sometimes be
deleted. For move constructors and move assignment operators, C++11
solved this problem by specifying that if a defaulted move special
member function turns out to be deleted, the function is ignored by
overload resolution. We therefore propose that a defaulted relocation
constructor that is defined as deleted is likewise excluded from the set
of candidate functions in all contexts.</li>
</ul>
<h2 data-number="4.3" id="conversions"><span class="header-section-number">4.3</span> Conversions<a href="#conversions" class="self-link"></a></h2>
<p>An rlvalue of type <em>cv1</em>
<code class="sourceCode default">T</code> can be implicitly converted to
an rlvalue of type <em>cv2</em>
<code class="sourceCode default">T</code> if <em>cv2</em> is more
cv-qualified than <em>cv1</em>.</p>
<p>An rlvalue of type <code class="sourceCode default">T</code> can be
implicitly converted to
<code class="sourceCode default">T&amp;&amp;</code>. This conversion
occurs automatically when the rlvalue expression is the left operand of
the <code class="sourceCode default">.</code> or
<code class="sourceCode default">.*</code> operator.</p>
<p>A prvalue of object type <code class="sourceCode default">T</code>
can be implicitly converted to an rlvalue of type
<code class="sourceCode default">T</code>, which has the effect of
materializing a temporary that is owned by the resulting rlvalue. During
overload resolution, this conversion is considered better than binding
to an rvalue reference or const lvalue reference. For example:</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="dt">void</span> foo<span class="op">(</span>T<span class="op">~</span> r<span class="op">)</span>;   <span class="co">// 1</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> foo<span class="op">(</span>T<span class="op">&amp;&amp;</span> r<span class="op">)</span>;  <span class="co">// 2</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><span class="dt">int</span> main<span class="op">()</span> <span class="op">{</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>    foo<span class="op">(</span>T<span class="op">{})</span>;</span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>A temporary of type <code class="sourceCode default">T</code> is
materialized and converted to an rlvalue. Then
<code class="sourceCode default">// 1</code> is called, and
<code class="sourceCode default">r</code> is bound to the resulting
rlvalue. When the owning reference
<code class="sourceCode default">r</code> is destroyed at the end of its
lifetime, it implicitly destroys the temporary object (unless
<code class="sourceCode default">r</code> was disengaged prior to the
end of its lifetime). The binding of the rlvalue to the temporary object
extends the storage lifetime for the object in the same manner as the
binding of any other reference and suppresses the implicit destruction
of the temporary object at the end of the full-expression in which it
was created; the rlvalue has ownership and is responsible for destroying
the object.</p>
<p>There is no implicit conversion from
<code class="sourceCode default">D~</code> to
<code class="sourceCode default">B~</code>, where
<code class="sourceCode default">B</code> is a base class of
<code class="sourceCode default">D</code>. Allowing such a conversion
would allow the referenced object to be passed to
<code class="sourceCode default">B</code>’s relocation constructor,
leaving the complete <code class="sourceCode default">D</code> object in
a partially destroyed state. Since such a conversion is not permitted,
the implicit destructor call at the end of the lifetime of an engaged
owning reference does not perform dynamic dispatch.</p>
<p>A glvalue of type <code class="sourceCode default">T</code> can be
explicitly converted to <code class="sourceCode default">T~</code> by
<code class="sourceCode default">static_cast</code>. This generates an
rlvalue referring to the object that the glvalue refers to, which
implies that this rlvalue will be responsible for destroying the object,
and the caller must ensure that they do not otherwise destroy the
object. Such casts should therefore generally be used only with objects
that have dynamic storage duration.</p>
<p>An rlvalue of type <code class="sourceCode default">T</code> decays
to simply <code class="sourceCode default">T</code> when deduced by
value. An owning reference behaves like any other reference when named
by a <em>simple-capture</em>. As when capturing a variable of object
type, the programmer must ensure that the lambda closure object does not
outlive the captured entity, lest the reference become dangling. A
lambda closure object cannot have an owning reference member, for
reasons that are discussed in Section 4.7.</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="kw">struct</span> T <span class="op">{</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> m;</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> U<span class="op">&gt;</span></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> g<span class="op">(</span>U u<span class="op">)</span>;</span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> f1<span class="op">(</span>T<span class="op">~</span> ref<span class="op">)</span> <span class="op">{</span></span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a>    g<span class="op">(</span>reloc ref<span class="op">)</span>;</span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true" tabindex="-1"></a>      <span class="co">// Calls `g&lt;T&gt;`, not `g&lt;T~&gt;`;</span></span>
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true" tabindex="-1"></a>      <span class="co">// the parameter `u` is relocated from the object that `ref` refers to.</span></span>
<span id="cb4-12"><a href="#cb4-12" aria-hidden="true" tabindex="-1"></a>      <span class="co">// `ref` is disengaged and the lifetime of the object `ref` refers to ends.</span></span>
<span id="cb4-13"><a href="#cb4-13" aria-hidden="true" tabindex="-1"></a>    g<span class="op">(</span>reloc ref<span class="op">)</span>;  <span class="co">// ill formed</span></span>
<span id="cb4-14"><a href="#cb4-14" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb4-15"><a href="#cb4-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-16"><a href="#cb4-16" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> f2<span class="op">(</span>T<span class="op">~</span> ref<span class="op">)</span> <span class="op">{</span></span>
<span id="cb4-17"><a href="#cb4-17" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> result <span class="op">=</span> <span class="op">[</span>ref<span class="op">]</span> <span class="op">{</span> <span class="cf">return</span> ref<span class="op">.</span>m; <span class="op">}</span>;</span>
<span id="cb4-18"><a href="#cb4-18" aria-hidden="true" tabindex="-1"></a>      <span class="co">// The closure type has a member of type `T`, which is *copied* from the</span></span>
<span id="cb4-19"><a href="#cb4-19" aria-hidden="true" tabindex="-1"></a>      <span class="co">// object that `ref` refers to.</span></span>
<span id="cb4-20"><a href="#cb4-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-21"><a href="#cb4-21" aria-hidden="true" tabindex="-1"></a>    g<span class="op">(</span>reloc ref<span class="op">)</span>;  <span class="co">// OK; `ref` was not previously disengaged.</span></span>
<span id="cb4-22"><a href="#cb4-22" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-23"><a href="#cb4-23" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> result;</span>
<span id="cb4-24"><a href="#cb4-24" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb4-25"><a href="#cb4-25" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-26"><a href="#cb4-26" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> f3<span class="op">(</span>T<span class="op">~</span> ref<span class="op">)</span> <span class="op">{</span></span>
<span id="cb4-27"><a href="#cb4-27" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> result <span class="op">=</span> <span class="op">[&amp;</span>ref<span class="op">]</span> <span class="op">{</span> <span class="cf">return</span> ref<span class="op">.</span>m; <span class="op">}</span>;</span>
<span id="cb4-28"><a href="#cb4-28" aria-hidden="true" tabindex="-1"></a>    g<span class="op">(</span>result<span class="op">)</span>;  <span class="co">// OK</span></span>
<span id="cb4-29"><a href="#cb4-29" aria-hidden="true" tabindex="-1"></a>    </span>
<span id="cb4-30"><a href="#cb4-30" aria-hidden="true" tabindex="-1"></a>    g<span class="op">(</span>reloc ref<span class="op">)</span>;  <span class="co">// OK; `ref` was not previously disengaged.</span></span>
<span id="cb4-31"><a href="#cb4-31" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-32"><a href="#cb4-32" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> result;  <span class="co">// UB; the reference is now dangling.</span></span>
<span id="cb4-33"><a href="#cb4-33" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<h2 data-number="4.4" id="relocation-of-automatic-variables"><span class="header-section-number">4.4</span> Relocation of automatic
variables<a href="#relocation-of-automatic-variables" class="self-link"></a></h2>
<p>We propose to change the current model of automatic variables to
allow them to be relocated using the
<code class="sourceCode default">reloc</code> operator. Automatic
variables that are not passed to the
<code class="sourceCode default">reloc</code> operator will continue to
be implicitly destroyed upon scope exit, just as they always have been —
though that mechanism now becomes defined in terms of owning
references.</p>
<p>To accomplish these objectives, we propose that for each automatic
variable, <code class="sourceCode default">x</code>, an implicit owning
reference (call it <code class="sourceCode default">__x~</code>) is
considered to be declared immediately after the locus of
<code class="sourceCode default">x</code>’s declaration in the same
scope. Immediately after its declaration,
<code class="sourceCode default">__x~</code> is engaged and owns
<code class="sourceCode default">x</code>.
<code class="sourceCode default">x</code> is no longer inherently
implicitly destroyed when it goes out of scope, but since
<code class="sourceCode default">__x~</code> owns
<code class="sourceCode default">x</code>, it will destroy
<code class="sourceCode default">x</code> upon scope exit, unless some
other owning reference takes over ownership of
<code class="sourceCode default">x</code> first or an rlvalue referring
to <code class="sourceCode default">x</code> has been passed to a
relocation constructor or otherwise disengaged.
<code class="sourceCode default">__x~</code> cannot be named directly
but is needed to define the
<code class="sourceCode default">reloc</code> operator (see below). An
<em>id-expression</em> naming <code class="sourceCode default">x</code>
is ill formed if <code class="sourceCode default">__x~</code> is
disengaged.</p>
<p>Although one might occasionally want to construct a new object in the
storage location designated by <code class="sourceCode default">x</code>
and re-engage <code class="sourceCode default">__x~</code> to that
object, we do not currently propose to allow
<code class="sourceCode default">x</code> to be named for such purposes,
nor do we propose any method by which a disengaged owning reference can
be re-engaged, because of the complexity of specifying such a feature
and because the safety of doing so isn’t clear. See Appendix A for more
discussion.</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> T <span class="op">{</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> m;</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> main<span class="op">()</span> <span class="op">{</span></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>    T x <span class="op">=</span> <span class="op">{</span><span class="dv">0</span><span class="op">}</span>;</span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>    T y;</span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a>    T<span class="op">~</span> r <span class="op">=</span> reloc x;  <span class="co">// `__x~` is disengaged; `r` owns `x`.</span></span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a>    <span class="op">++</span>x<span class="op">.</span>m;  <span class="co">// ill formed; `__x~` is disengaged.</span></span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a>    <span class="op">++</span>r<span class="op">.</span>m;  <span class="co">// OK; `r` is an lvalue.</span></span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a>    <span class="co">// `r` goes out of scope and destroys `x`.</span></span>
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true" tabindex="-1"></a>    <span class="co">// `__y~` goes out of scope and destroys `y`.</span></span>
<span id="cb5-12"><a href="#cb5-12" aria-hidden="true" tabindex="-1"></a>    <span class="co">// `y` goes out of scope; `~T()` is not implicitly called.</span></span>
<span id="cb5-13"><a href="#cb5-13" aria-hidden="true" tabindex="-1"></a>    <span class="co">// `__x~` goes out of scope and does nothing since already disengaged.</span></span>
<span id="cb5-14"><a href="#cb5-14" aria-hidden="true" tabindex="-1"></a>    <span class="co">// `x` goes out of scope; `~T()` is not implicitly called.</span></span>
<span id="cb5-15"><a href="#cb5-15" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<h2 data-number="4.5" id="the-reloc-operator"><span class="header-section-number">4.5</span> The
<code class="sourceCode default">reloc</code> operator<a href="#the-reloc-operator" class="self-link"></a></h2>
<p>The <code class="sourceCode default">reloc</code> operator is used to
obtain an rlvalue expression that owns a given entity and to disengage
the previous owner. For these purposes, it may be applied to the
following categories of <em>id-expressions</em>.
</p>
<ul>
<li>When the operand is an <em>id-expression</em> (possibly
parenthesized) denoting an automatic variable
<code class="sourceCode default">x</code> of type
<code class="sourceCode default">T~</code> belonging to a block scope or
function parameter scope associated with the immediately enclosing
function definition, the result is an rlvalue referring to the object
that <code class="sourceCode default">x</code> referred to;
<code class="sourceCode default">x</code> is thereby disengaged.</li>
<li>When the operand is an <em>id-expression</em> (possibly
parenthesized) denoting an automatic variable
<code class="sourceCode default">x</code> of object type belonging to a
block scope associated with the immediately enclosing function
definition, the result is
<code class="sourceCode default">reloc __x~</code>.</li>
</ul>
<p>We do not propose allowing
<code class="sourceCode default">reloc</code> to be applied to a
reference variable that is extending the lifetime of the temporary
object it is bound to, because the reference might be to a subobject of
the temporary object. See Section 4.3.</p>
<p>Because some ABIs require function parameters of object type to be
destroyed on the caller side, applying
<code class="sourceCode default">reloc</code> to the names of such
parameters is not permitted in general; if the programmer wishes to
relocate from a function parameter, they should ensure that the function
parameter is declared with type
<code class="sourceCode default">T~</code> rather than
<code class="sourceCode default">T</code>. However, as an optional
add-on to Part I, we propose adopting an idea from <span class="citation" data-cites="D2785">[<a href="#ref-D2785" role="doc-biblioref">D2785</a>]</span>: If
<code class="sourceCode default">T</code> is a relocate-only type (i.e.,
a type that has no eligible copy constructor and no eligible move
constructor but does have an eligible relocation constructor), then it
is permitted to relocate from a
<code class="sourceCode default">T</code> function parameter (implying
that callee-destroy is required for such types, which currently do not
exist).</p>
<h2 data-number="4.6" id="reference-collapsing-and-perfect-forwarding"><span class="header-section-number">4.6</span> Reference collapsing and
perfect forwarding<a href="#reference-collapsing-and-perfect-forwarding" class="self-link"></a></h2>
<p>Because <code class="sourceCode default">T~</code> is a reference
type, there shall be no pointers to
<code class="sourceCode default">T~</code>, references to
<code class="sourceCode default">T~</code>, or arrays of
<code class="sourceCode default">T~</code>. Writing out a type such as
<code class="sourceCode default">T~&amp;</code> directly is ill formed.
However, owning references participate in reference collapsing.</p>
<ul>
<li>The composition of “owning reference to” and “lvalue reference to”
(in either order) is “lvalue reference to.”</li>
<li>The composition of “owning reference to” and “rvalue reference to”
(in either order) is “rvalue reference to.”</li>
<li>The composition of “owning reference to” and “owning reference to”
is “owning reference to.”</li>
</ul>
<p>These reference collapsing rules follow the “principle of lesser
privilege” that currently governs the collapsing of lvalue and rvalue
references. Owning references give the most privileges (the holder is
permitted to destroy the object it refers to, possibly relocating its
value to another object), followed by rvalue references (the holder is
permitted to take ownership of the held resources, leaving the object in
a moved-from state, but is not permitted to destroy the object), and
lvalue references.</p>
<p>It follows that in the presence of owning references, forwarding
references should be spelled
“<code class="sourceCode default">T~</code>”, where
<code class="sourceCode default">T</code> is a template parameter of a
function that has a parameter of type
<code class="sourceCode default">T~</code>. The template argument for
<code class="sourceCode default">T</code> is then deduced as an lvalue
reference, rvalue reference, or nonreference when the function argument
is, respectively, an lvalue, xvalue, or rlvalue. (Since, as discussed in
Section 4.3, a prvalue of type <code class="sourceCode default">U</code>
prefers to be bound to <code class="sourceCode default">U~</code> rather
than <code class="sourceCode default">U&amp;&amp;</code>, using such a
prvalue as the function argument will also result in
<code class="sourceCode default">T</code> being deduced as
<code class="sourceCode default">U</code>.) A forwarding reference that
is spelled <code class="sourceCode default">T&amp;&amp;</code> can bind
to an rlvalue of type <code class="sourceCode default">U</code> but
cannot forward it as an rlvalue; the function parameter type will be
<code class="sourceCode default">U&amp;&amp;</code>, not
<code class="sourceCode default">U~</code>.</p>
<p>The issue of how to actually perform forwarding (which is typically
done using an expression of the form
<code class="sourceCode default">std::forward&lt;T&gt;(r)</code>, <code class="sourceCode default">static_cast&lt;T&amp;&amp;&gt;(r)</code>, or
<code class="sourceCode default">static_cast&lt;decltype(r)&gt;(r)</code> in
current C++) is thorny. When <code class="sourceCode default">r</code>
is an owning reference, <code class="sourceCode default">reloc</code>
must be used so that the disengagement of
<code class="sourceCode default">r</code> that must be performed at the
call site is visible to the compiler. However, it is essential to
support a single syntax that perfectly forwards
<code class="sourceCode default">r</code> regardless of whether it is an
lvalue reference, rvalue reference, or owning reference; any alternative
that would force users to implement a compile-time switch to call
<code class="sourceCode default">reloc</code> on forwarding references
of owning reference type — and an ordinary
<code class="sourceCode default">static_cast</code> (or call to
<code class="sourceCode default">std::forward</code>) in other cases —
is not workable. For this reason, we propose to resurrect the proposal
for a unary <code class="sourceCode default">&gt;&gt;</code> forwarding
operator, which was described in <span class="citation" data-cites="P0644R1">[<a href="#ref-P0644R1" role="doc-biblioref">P0644R1</a>]</span> and rejected in Albuquerque
(November 2017). When applied to a forwarding reference that is an
owning reference, <code class="sourceCode default">&gt;&gt;</code> would
be equivalent to <code class="sourceCode default">reloc</code>, and when
applied to any other entity,
<code class="sourceCode default">&gt;&gt;</code> would be equivalent to
a <code class="sourceCode default">static_cast</code> as originally
proposed. A function template that needs to perfectly forward one or
more arguments would then take this form:</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">class</span> T, <span class="kw">class</span><span class="op">...</span> Args<span class="op">&gt;</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>foo<span class="op">&lt;</span>T<span class="op">&gt;</span> make_foo<span class="op">(</span>Args<span class="op">~...</span> args<span class="op">)</span> <span class="op">{</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> foo<span class="op">&lt;</span>T<span class="op">&gt;(&gt;&gt;</span> args<span class="op">...)</span>;</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>As an alternative to the
<code class="sourceCode default">&gt;&gt;</code> forwarding operator, we
propose to adopt an idea from <span class="citation" data-cites="D2785">[<a href="#ref-D2785" role="doc-biblioref">D2785</a>]</span>, wherein
<code class="sourceCode default">reloc</code> can also be applied to
lvalue references and rvalue references, not only to the entities
described in the previous section. Using
<code class="sourceCode default">reloc</code> as the forwarding
operator, the above function template could be written:</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">class</span> T, <span class="kw">class</span><span class="op">...</span> Args<span class="op">&gt;</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>foo<span class="op">&lt;</span>T<span class="op">&gt;</span> make_foo<span class="op">(</span>Args<span class="op">~...</span> args<span class="op">)</span> <span class="op">{</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> foo<span class="op">&lt;</span>T<span class="op">&gt;(</span>reloc args<span class="op">...)</span>;</span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>The main disadvantage of
<code class="sourceCode default">reloc</code> as the forwarding operator
is that it would use the same keyword for two essentially
<em>distinct</em> operators: an operator that disengages its operand to
allow the compiler to track who owns a particular object and an operator
that simply casts to lvalue reference or rvalue reference to facilitate
perfect forwarding. To mitigate this disadvantage, we propose that when
<code class="sourceCode default">reloc</code> is applied to an lvalue or
rvalue reference, that operand shall be an owning reference. This
restriction would not completely eliminate the inelegance and possible
confusion arising from the use of
<code class="sourceCode default">reloc</code> as the forwarding
operator. For this reason, we believe that the unary
<code class="sourceCode default">&gt;&gt;</code> operator would provide
a better solution for perfect forwarding in the presence of owning
references.</p>
<p>A third option is to specify that
<code class="sourceCode default">static_cast&lt;T~&gt;(r)</code>
implicitly applies <code class="sourceCode default">reloc</code> to
<code class="sourceCode default">r</code> when
<code class="sourceCode default">r</code> is a forwarding reference with
declared type <code class="sourceCode default">T~</code>. The above
function template could then be written:</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="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> T, <span class="kw">class</span><span class="op">...</span> Args<span class="op">&gt;</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>foo<span class="op">&lt;</span>T<span class="op">&gt;</span> make_foo<span class="op">(</span>Args<span class="op">~...</span> args<span class="op">)</span> <span class="op">{</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> foo<span class="op">&lt;</span>T<span class="op">&gt;(</span><span class="kw">static_cast</span><span class="op">&lt;</span>Args<span class="op">~&gt;(</span>args<span class="op">)...)</span>;</span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>This syntax is much more verbose than the
<code class="sourceCode default">&gt;&gt;</code> and
<code class="sourceCode default">reloc</code> syntaxes, and would likely
increase the popularity of <code class="sourceCode default">FWD</code>
macros. We consider this outcome undesirable. We also believe that it is
dangerous to allow the
<code class="sourceCode default">static_cast</code> operator, which can
accept any expression as an operand, to implicitly disengage its operand
only when that operand has a very specific form. We do not propose this
syntax for forwarding, but include it only for completeness.</p>
<p>We discuss some alternative specifications for forwarding references
in Appendix B.</p>
<h2 data-number="4.7" id="restrictions-on-owning-references"><span class="header-section-number">4.7</span> Restrictions on owning
references<a href="#restrictions-on-owning-references" class="self-link"></a></h2>
<p>A variable of owning reference type must have automatic storage
duration. The purpose of this rule is to make it harder to accidentally
create an owning reference that later becomes dangling. The rules we
propose make it ill formed to reference an owning reference of automatic
storage duration after it has become disengaged; there does not seem to
be a similar strategy to prevent such unsafe accesses to owning
references of static and dynamic storage duration. In the particular
case of dynamic storage duration, there is a considerable risk that an
owning reference attempts to destroy an object whose storage has already
been released or reused (e.g., a variable of automatic storage duration
whose block has already been exited).</p>
<p>Because owning reference variables are required to have automatic
storage duration, they are not permitted as nonstatic data members. (The
alternative — namely to make classes containing nonstatic data members
of owning reference type ineligible to have any storage duration other
than automatic storage duration — would create more problems than it
solves.)</p>
<p>In addition, <code class="sourceCode default">~</code> is not
permitted as a <em>ref-qualifier</em> in a function declarator; no
variable could take ownership in such a case (considering that
<code class="sourceCode default">this</code> is a pointer).</p>
<p>Explicit object parameters are permitted to have owning reference
type. Note that calling a function with such an explicit object
parameter will usually result in the implicit destruction of the object
argument:</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><span class="kw">struct</span> S <span class="op">{</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>    <span class="co">/* ... */</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">void</span> self_destruct<span class="op">(</span><span class="kw">this</span> S<span class="op">~</span> self<span class="op">)</span>;</span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>S s;</span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a><span class="op">(</span>reloc s<span class="op">).</span>self_destruct<span class="op">()</span>;</span></code></pre></div>
<p>We discuss an application for explicit object parameters of owning
reference type in Part III.</p>
<p>Structured binding declarations are not permitted to have owning
reference type; they suffer from the same issue as
<code class="sourceCode default">~</code> on an implicit object member
function: you can’t actually name the entity to which the
<em>ref-qualifier</em> applies (known as <em>e</em> in <span>9.6
<a href="https://wg21.link/dcl.struct.bind">[dcl.struct.bind]</a></span>).</p>
<h2 data-number="4.8" id="further-examples-of-disengagement-and-control-flow"><span class="header-section-number">4.8</span> Further examples of
disengagement and control flow<a href="#further-examples-of-disengagement-and-control-flow" class="self-link"></a></h2>
<p>If all flow-of-control paths through a particular branch result in a
jump that exits the scope to which an owning reference belongs, the
other branches do not implicitly disengage the owning reference. The
reason for this exception to the usual implicit disengagement rules is
that the branch containing the jump cannot rejoin the other branches, so
implicit disengagement is not required in the other branches to prevent
a situation in which the owning reference may or may not be disengaged
after such rejoining.</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">struct</span> T <span class="op">{</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>    <span class="dt">void</span> method<span class="op">()</span>;</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> g<span class="op">(</span>T<span class="op">)</span>;</span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a>T f<span class="op">(</span><span class="dt">bool</span> b<span class="op">)</span> <span class="op">{</span></span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a>    T t;</span>
<span id="cb10-9"><a href="#cb10-9" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="op">(</span>b<span class="op">)</span> <span class="op">{</span></span>
<span id="cb10-10"><a href="#cb10-10" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> reloc t;</span>
<span id="cb10-11"><a href="#cb10-11" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb10-12"><a href="#cb10-12" aria-hidden="true" tabindex="-1"></a>        t<span class="op">.</span>method<span class="op">()</span>;  <span class="co">// OK</span></span>
<span id="cb10-13"><a href="#cb10-13" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb10-14"><a href="#cb10-14" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> reloc t;  <span class="co">// OK</span></span>
<span id="cb10-15"><a href="#cb10-15" aria-hidden="true" tabindex="-1"></a>    <span class="co">// `__t~` is disengaged and goes out of scope.</span></span>
<span id="cb10-16"><a href="#cb10-16" aria-hidden="true" tabindex="-1"></a>    <span class="co">// `t` goes out of scope.</span></span>
<span id="cb10-17"><a href="#cb10-17" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>A jump construct is not permitted to jump from a point where an
owning reference is disengaged to a point that follows the definition of
the owning reference but precedes an <em>id-expression</em> naming the
owning reference. An implicit jump from the end of a loop back to its
beginning is considered to occur.</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">int</span> g<span class="op">(</span><span class="dt">int</span><span class="op">~</span> r<span class="op">)</span>;</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-3"><a href="#cb11-3" 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> r<span class="op">)</span> <span class="op">{</span></span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>    <span class="cf">while</span> <span class="op">(</span><span class="kw">true</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a>        g<span class="op">(</span>reloc r<span class="op">)</span>;  <span class="co">// ill formed</span></span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb11-8"><a href="#cb11-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-9"><a href="#cb11-9" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> f2<span class="op">(</span><span class="dt">int</span><span class="op">~</span> r<span class="op">)</span> <span class="op">{</span></span>
<span id="cb11-10"><a href="#cb11-10" aria-hidden="true" tabindex="-1"></a>    <span class="cf">while</span> <span class="op">(</span><span class="kw">true</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb11-11"><a href="#cb11-11" aria-hidden="true" tabindex="-1"></a>        <span class="dt">int</span> x <span class="op">=</span> <span class="dv">0</span>;</span>
<span id="cb11-12"><a href="#cb11-12" aria-hidden="true" tabindex="-1"></a>        g<span class="op">(</span>reloc x<span class="op">)</span>;  <span class="co">// OK</span></span>
<span id="cb11-13"><a href="#cb11-13" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">(</span>rand<span class="op">()</span> <span class="op">%</span> <span class="dv">8</span> <span class="op">==</span> <span class="dv">0</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb11-14"><a href="#cb11-14" aria-hidden="true" tabindex="-1"></a>            g<span class="op">(</span>reloc r<span class="op">)</span>;</span>
<span id="cb11-15"><a href="#cb11-15" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span>;  <span class="co">// OK</span></span>
<span id="cb11-16"><a href="#cb11-16" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb11-17"><a href="#cb11-17" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb11-18"><a href="#cb11-18" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>When an rlvalue expression is evaluated and is not otherwise
disengaged by the end of the containing full-expression, the rlvalue is
implicitly disengaged as part of the last step in evaluating the
full-expression; the timing of this implicit disengagement is the same
as the timing of the implicit destructor call for a hypothetical
temporary object that was created at the point at which the rlvalue
expression was evaluated. This implicit disengagement can occur, for
example, when the rlvalue expression is a discarded-value expression or
when it is converted to an xvalue instead of being used to initialize an
owning reference variable.</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="dt">void</span> f<span class="op">(</span>T<span class="op">~</span> ref<span class="op">)</span> <span class="op">{</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>    U<span class="op">{}</span>, <span class="op">(</span>reloc ref<span class="op">)</span>, V<span class="op">{}</span>;</span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a>      <span class="co">// `V` object destroyed, then `ref.~T()` called, and then `U` object destroyed.</span></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>If an evaluation that disengages an owning reference variable is
indeterminately sequenced or unsequenced relative to another evaluation
in the same full-expression that names the owning reference variable
(where an <em>id-expression</em> naming an automatic variable is
considered to name its implicit owning reference for the purpose of this
rule), the program is ill formed because we have no guarantee that the
latter occurs before the former.</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">struct</span> S <span class="op">{</span></span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>    S<span class="op">(</span><span class="dt">int</span> x, <span class="dt">int</span><span class="op">~</span> r<span class="op">)</span>;</span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> bar<span class="op">(</span><span class="dt">int</span><span class="op">~</span> r<span class="op">)</span> <span class="op">{</span></span>
<span id="cb13-6"><a href="#cb13-6" aria-hidden="true" tabindex="-1"></a>    S s1<span class="op">(</span>r, reloc r<span class="op">)</span>;  <span class="co">// Ill formed; `reloc r` may occur before the copy.</span></span>
<span id="cb13-7"><a href="#cb13-7" aria-hidden="true" tabindex="-1"></a>    S s2<span class="op">{</span>r, reloc r<span class="op">}</span>;  <span class="co">// OK; `x` is copied from `r`, and then `reloc r` is evaluated.</span></span>
<span id="cb13-8"><a href="#cb13-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>See Part II for an example in which this rule must be carefully
understood.</p>
<p>Because the evaluation of a ternary conditional expression entails
control flow, it performs implicit disengagement in the same manner as
an <code class="sourceCode default">if</code> statement:</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="dt">int</span> bar<span class="op">(</span><span class="dt">int</span><span class="op">~)</span>;</span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> foo<span class="op">(</span><span class="dt">bool</span> b<span class="op">)</span> <span class="op">{</span></span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> x <span class="op">=</span> <span class="dv">0</span>;</span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> y <span class="op">=</span> b <span class="op">?</span> bar<span class="op">(</span>reloc x<span class="op">)</span> <span class="op">:</span> x;</span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a>        <span class="co">// OK; if `b` is false, `__x~` is implicitly disengaged after the third</span></span>
<span id="cb14-7"><a href="#cb14-7" aria-hidden="true" tabindex="-1"></a>        <span class="co">// operand is evaluated.</span></span>
<span id="cb14-8"><a href="#cb14-8" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> z <span class="op">=</span> x;  <span class="co">// Ill formed; `__x~` is disengaged.</span></span>
<span id="cb14-9"><a href="#cb14-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<h2 data-number="4.9" id="miscellaneous"><span class="header-section-number">4.9</span> Miscellaneous<a href="#miscellaneous" class="self-link"></a></h2>
<p>Some of this section’s subsections propose new library facilities.
The library facilities that will be proposed in a future revision of
this paper should Part I move forward are not exhaustively enumerated
herein.</p>
<h3 data-number="4.9.1" id="implicit-relocation-by-return-statements"><span class="header-section-number">4.9.1</span> Implicit relocation by
<code class="sourceCode default">return</code> statements<a href="#implicit-relocation-by-return-statements" class="self-link"></a></h3>
<p>The <code class="sourceCode default">return x;</code> statements that
currently implicitly move will behave as if by
<code class="sourceCode default">return reloc x;</code> instead. Note
that if no relocation constructor is available, the prvalue of
<code class="sourceCode default">T~</code> will implicitly convert to an
rvalue of <code class="sourceCode default">T</code>, so the move
constructor will be selected. The behavior of returning an object whose
type does not have a relocation constructor (or whose type has a
defaulted relocation constructor that is defined as deleted) will
therefore be unchanged by this rule.</p>
<h3 data-number="4.9.2" id="pseudo-destructor-call-on-owning-reference"><span class="header-section-number">4.9.2</span> Pseudo-destructor call on
owning reference<a href="#pseudo-destructor-call-on-owning-reference" class="self-link"></a></h3>
<p>If <code class="sourceCode default">x</code> is an
<em>id-expression</em> (possibly parenthesized) naming an automatic
variable of type <code class="sourceCode default">T~</code> belonging to
a block scope or function parameter scope associated with the
immediately enclosing function definition, the expression
<code class="sourceCode default">x.~T()</code> destroys the referenced
object and disengages <code class="sourceCode default">x</code>. (This
effect can also be achieved by evaluating
<code class="sourceCode default">reloc x</code> in a discarded-value
expression context, but the pseudo-destructor syntax is more
evocative.)</p>
<h3 data-number="4.9.3" id="the-stdforce_relocate-function"><span class="header-section-number">4.9.3</span> The
<code class="sourceCode default">std::force_relocate</code> function<a href="#the-stdforce_relocate-function" class="self-link"></a></h3>
<p>We propose that a library function,
<code class="sourceCode default">std::force_relocate</code>, shall be
provided by <code class="sourceCode default">&lt;utility&gt;</code>:</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><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> T<span class="op">&gt;</span></span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> T<span class="op">~</span> force_relocate<span class="op">(</span>T<span class="op">&amp;&amp;</span> r<span class="op">)</span> <span class="op">{</span></span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="kw">static_cast</span><span class="op">&lt;</span>T<span class="op">~&gt;(</span>r<span class="op">)</span>;</span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>The <code class="sourceCode default">std::force_relocate</code>
function can be used by, e.g., a
<code class="sourceCode default">std::vector</code>-like container when
reallocating. Let’s look at an example of how such reallocation can be
performed. The reallocation does not suppress any implicit destructor
call that would occur for its argument; the caller must remember not to
destroy the source object separately.</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">class</span> T<span class="op">&gt;</span></span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> my_vector<span class="op">&lt;</span>T<span class="op">&gt;::</span>reallocate<span class="op">(</span>size_type new_capacity<span class="op">)</span> <span class="op">{</span></span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a>    T<span class="op">*</span> new_buf <span class="op">=</span> std<span class="op">::</span>allocator_traits<span class="op">&lt;</span>Alloc<span class="op">&gt;::</span>allocate<span class="op">(</span>alloc_, new_capacity<span class="op">)</span>;</span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> <span class="op">(</span>size_type i <span class="op">=</span> <span class="dv">0</span>; i <span class="op">&lt;</span> size_; i<span class="op">++)</span> <span class="op">{</span></span>
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a>        <span class="op">::</span><span class="kw">new</span> <span class="op">(</span><span class="kw">static_cast</span><span class="op">&lt;</span><span class="dt">void</span><span class="op">*&gt;(</span>new_buf <span class="op">+</span> i<span class="op">))</span> T<span class="op">(</span>std<span class="op">::</span>force_relocate<span class="op">(</span>buf_<span class="op">[</span>i<span class="op">]))</span>;</span>
<span id="cb16-6"><a href="#cb16-6" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb16-7"><a href="#cb16-7" aria-hidden="true" tabindex="-1"></a>    capacity_ <span class="op">=</span> new_capacity;</span>
<span id="cb16-8"><a href="#cb16-8" aria-hidden="true" tabindex="-1"></a>    buf_ <span class="op">=</span> new_buf;</span>
<span id="cb16-9"><a href="#cb16-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>(Factory functions such as <code class="sourceCode default">std::allocator_traits&lt;Alloc&gt;::construct</code>
should be updated to accept a pack of the new forwarding reference,
<code class="sourceCode default">Args~...</code>. We have not yet
enumerated all Standard Library function templates to which this change
should be made. After the Standard Library function templates are
updated with this change, the above placement-new expression should be
replaced by a call to <code class="sourceCode default">std::allocator_traits&lt;Alloc&gt;::construct</code>.)</p>
<h3 data-number="4.9.4" id="the-stdrelocate_ptr-smart-pointer"><span class="header-section-number">4.9.4</span> The
<code class="sourceCode default">std::relocate_ptr</code> smart
pointer<a href="#the-stdrelocate_ptr-smart-pointer" class="self-link"></a></h3>
<p>We propose a smart pointer type that is similar to
<code class="sourceCode default">std::unique_ptr</code> but can be only
relocated (not moved). Like
<code class="sourceCode default">std::unique_ptr</code>, the smart
pointer type guarantees that the deleter it holds will eventually be
called to release the resources owned by the raw pointer it owns.
However, while a <code class="sourceCode default">std::unique_ptr</code>
can be accidentally dereferenced after it has been moved from (and
become null), a
<code class="sourceCode default">std::relocate_ptr</code> cannot be
accessed in any way after it has been relocated from and omits the
<code class="sourceCode default">release</code> and
<code class="sourceCode default">reset</code> functions that can be used
to change its value to null. We expect that
<code class="sourceCode default">std::relocate_ptr</code> can be used in
place of <code class="sourceCode default">std::unique_ptr</code> in most
situations where <code class="sourceCode default">std::unique_ptr</code>
is currently used, leading to safer code.</p>
<h3 data-number="4.9.5" id="the-stddisengage-function"><span class="header-section-number">4.9.5</span> The
<code class="sourceCode default">std::disengage</code> function<a href="#the-stddisengage-function" class="self-link"></a></h3>
<p>We propose a library function,
<code class="sourceCode default">std::disengage</code>:</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="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> T<span class="op">&gt;</span></span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="dt">void</span> disengage<span class="op">(</span>T<span class="op">~)</span> <span class="kw">requires</span> is_object_v<span class="op">&lt;</span>T<span class="op">&gt;</span>;</span></code></pre></div>
<p>Calling <code class="sourceCode default">disengage</code>
(unsurprisingly) disengages the rlvalue argument and ends the lifetime
of the object to which it refers, <em>without</em> calling any
destructors or relocation constructors. (Therefore, the effect of
calling <code class="sourceCode default">disengage</code> is different
from that of an <em>implicit</em> disengagement that occurs when
<code class="sourceCode default">reloc</code> is applied to an owning
reference or when the compiler inserts a disengagement along some
branches of control flow; such implicit disengagements always call the
destructor.)</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="pp">#include </span><span class="im">&lt;utility&gt;</span></span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> T <span class="op">{</span></span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> m;</span>
<span id="cb18-5"><a href="#cb18-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb18-6"><a href="#cb18-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-7"><a href="#cb18-7" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> main<span class="op">()</span> <span class="op">{</span></span>
<span id="cb18-8"><a href="#cb18-8" aria-hidden="true" tabindex="-1"></a>    T x<span class="op">{</span><span class="dv">1</span><span class="op">}</span>;</span>
<span id="cb18-9"><a href="#cb18-9" aria-hidden="true" tabindex="-1"></a>    T<span class="op">&amp;</span> r <span class="op">=</span> x;</span>
<span id="cb18-10"><a href="#cb18-10" aria-hidden="true" tabindex="-1"></a>    std<span class="op">::</span>disengage<span class="op">(</span>x<span class="op">)</span>;  <span class="co">// OK; `x.~T()` not called.</span></span>
<span id="cb18-11"><a href="#cb18-11" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> y <span class="op">=</span> x<span class="op">.</span>m;  <span class="co">// Ill formed; `x` is disengaged.</span></span>
<span id="cb18-12"><a href="#cb18-12" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> z <span class="op">=</span> r<span class="op">.</span>m;  <span class="co">// UB; dangling reference</span></span>
<span id="cb18-13"><a href="#cb18-13" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Not particularly useful in Part I, the effect of
<code class="sourceCode default">std::disengage</code> is purely to end
the lifetime of the object to which the rlvalue refers. This effect can
be easily misused to subvert RAII but may be useful in user-provided
relocation constructors; see Part II.</p>
<p>A user cannot implement
<code class="sourceCode default">std::disengage</code> because it
behaves as if it stashes away an owning reference in some place where
the latter can live until the program terminates, which is not possible
in user code since all owning references have automatic storage
duration.</p>
<h1 data-number="5" id="part-ii-user-provided-relocation-constructors"><span class="header-section-number">5</span> Part II: User-provided relocation
constructors<a href="#part-ii-user-provided-relocation-constructors" class="self-link"></a></h1>
<p>If Part I of this proposal is adopted, we expect that the vast
majority of relocatable types will be trivially relocatable, and for the
vast majority of nontrivially relocatable types, the defaulted
relocation constructor (which will move then destroy) will do the right
thing, because the necessary nontrivial work will already have been done
when writing the move constructor and destructor. However, as
relocate-only types become more common, so will class types that cannot
be moved because they contain relocate-only subobjects. In some cases,
patch-ups will need to be performed after memberwise relocation of these
types, and since such types cannot be given a move constructor that
performs the patch-ups, users must be able to write their own relocation
constructor. In other words, if Part I is adopted without provisions to
enable users to provide their own relocation constructors, relocation in
C++ will become a victim of its own success. However, we propose Part II
separately from Part I because specifying the semantics of user-provided
relocation constructors involves additional complexities with less
clear-cut solutions.</p>
<p>When users are allowed to write their own relocation constructors,
the source object <em>must</em> not be implicitly destroyed, since the
relocation operation takes the place of destruction. Therefore, the
relocation constructor must ensure that each subobject of the source
object is either relocated from or destroyed to avoid leaks. For
usability and safety, we must ensure that destruction occurs
automatically for each source subobject that is not relocated (i.e., the
burden should not be on the user to remember to destroy them). (A
relocation constructor thus offers the same guarantee with respect to
its source object as a destructor, except it destroys the subobjects in
the opposite order.) If the implicit destruction of subobjects that were
not relocated does not occur in the <em>ctor-initializer</em>, then the
body of the relocation constructor will see a source object that is
partially alive. This situation is likely to result in unsafe code. The
desire to prevent this situation leads to the conclusion that implicit
destruction should occur in the <em>ctor-initializer</em>.</p>
<p>For the compiler to know which source subobjects to implicitly
destroy, there must be a mechanism for the compiler to know which
destination subobjects will be constructed by relocation from the
corresponding source subobjects. The <span class="citation" data-cites="D2785">[<a href="#ref-D2785" role="doc-biblioref">D2785</a>]</span> approach in this area is for
relocation constructors to implicitly relocate each destination
subobject from the corresponding source subobject unless the subobject
is explicitly named in the <em>ctor-initializer</em>. However, since we
have owning references in our proposal, we can support more general
constructors that do not have the exact signature
<code class="sourceCode default">T::T(T~)</code>, and such constructors
can have additional parameters as well. This raises the question of
which such constructors should receive this implicit relocation
treatment. We explain a use case for such extended relocation
constructors below.</p>
<p>We propose the <code class="sourceCode default">reloc</code>
specifier (distinct from the
<code class="sourceCode default">reloc</code> operator that was
introduced in Part I) that may be applied only to a parameter of a
constructor for type <code class="sourceCode default">T</code>, where
the parameter must have type <code class="sourceCode default">T~</code>
and at most one parameter may have this specifier. The use of this
specifier marks the corresponding parameter to have its subobjects
implicitly relocated to the destination subobject unless overridden by
the <em>ctor-initializer</em>. The
<code class="sourceCode default">reloc</code> specifier is an
implementation detail of the definition of the constructor and is not
part of the constructor’s signature. We recommend that it be omitted on
nondefining declarations of a constructor. The
<code class="sourceCode default">reloc</code> specifier also tells the
compiler to implicitly call
<code class="sourceCode default">std::disengage</code> on the owning
reference parameter when the <em>ctor-initializer</em> is left (either
because it has completed or because it was interrupted by an exception),
unless the constructor is a delegating constructor. When the
<em>ctor-initializer</em> completes normally, this implicit
disengagement is necessary because after the <em>ctor-initializer</em>
runs, each subobject of the <code class="sourceCode default">T</code>
object owned by the owning reference parameter will be either relocated
or destroyed; for the owning reference to also remain engaged and to be
destroyed at the end of the destructor, thus double-destroying the
object it would otherwise continue to own, would make no sense. When the
<em>ctor-initializer</em> is interrupted by an exception, implicit
disengagement is needed to ensure that the subobjects of the source
object that have already been relocated from or implicitly destroyed are
not destroyed a second time, since the entire source object’s destructor
would be called if the owning reference were not disengaged first.</p>
<p>The <code class="sourceCode default">reloc</code> specifier is not
permitted in a delegating constructor because its semantics of
performing memberwise relocation and destruction do not make sense for a
constructor that does not itself initialize any subobjects.</p>
<p>Note that if the programmer does not mark a parameter
<code class="sourceCode default">reloc</code> and instead attempts to
manually relocate from one of its subobjects in the
<em>ctor-initializer</em>, the compiler will tell the programmer that
the <code class="sourceCode default">reloc</code> operator can be
applied to only an <em>id-expression</em>, not to the class member
access or cast expression that they would need to write to reference the
subobject they are trying to relocate from. We recommend that
implementations try to provide a helpful diagnostic in such cases:</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="kw">struct</span> S <span class="op">{</span></span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a>    T d_foo;</span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a>    S<span class="op">(</span>S<span class="op">~</span> other<span class="op">)</span> <span class="op">:</span> d_foo<span class="op">(</span>reloc other<span class="op">.</span>d_foo<span class="op">)</span> <span class="op">{</span></span>
<span id="cb19-4"><a href="#cb19-4" aria-hidden="true" tabindex="-1"></a>                     <span class="co">// ^^^^^^^^^^^^^^^^^</span></span>
<span id="cb19-5"><a href="#cb19-5" aria-hidden="true" tabindex="-1"></a>                     <span class="co">// Possible error message:</span></span>
<span id="cb19-6"><a href="#cb19-6" aria-hidden="true" tabindex="-1"></a>                     <span class="co">// &quot;The `reloc` operator may only be applied to the name</span></span>
<span id="cb19-7"><a href="#cb19-7" aria-hidden="true" tabindex="-1"></a>                     <span class="co">// of a variable; to relocate from subobjects of `other`,</span></span>
<span id="cb19-8"><a href="#cb19-8" aria-hidden="true" tabindex="-1"></a>                     <span class="co">// declare `other` with the `reloc` specifier&quot;.</span></span>
<span id="cb19-9"><a href="#cb19-9" aria-hidden="true" tabindex="-1"></a>        std<span class="op">::</span>cout <span class="op">&lt;&lt;</span> <span class="st">&quot;S(S~)</span><span class="sc">\n</span><span class="st">&quot;</span>;</span>
<span id="cb19-10"><a href="#cb19-10" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb19-11"><a href="#cb19-11" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
<p>A possible extension (that we are not currently proposing) is to
extend the <code class="sourceCode default">reloc</code> specifier
(possibly spelled differently) to other kinds of parameters (typically
for copy and move constructors), with the same meaning of “use this
parameter as the default source for initialization of subobjects” (i.e.,
by copy or move depending on the parameter type). The implicit
disengagement would still apply to only owning references.</p>
<p>For the same reasons that we propose that relocation constructors be
implicitly <code class="sourceCode default">noexcept</code> when
implicitly declared or when explicitly defaulted on their first
declaration (see Part I), we also propose that every constructor having
a parameter that is declared
<code class="sourceCode default">reloc</code> be implicitly
<code class="sourceCode default">noexcept</code> and that it be a
diagnosable error if such a constructor is declared
<code class="sourceCode default">noexcept(false)</code>.</p>
<h2 data-number="5.1" id="example-relocate-only-small-vector"><span class="header-section-number">5.1</span> Example: Relocate-only small
vector<a href="#example-relocate-only-small-vector" class="self-link"></a></h2>
<p>A <em>small vector</em> is a class template that provides inline
storage for up to <code class="sourceCode default">N</code> objects of
type <code class="sourceCode default">T</code>, where
<code class="sourceCode default">N</code> is a template parameter and
either employs dynamic memory allocation when the user attempts to store
more than <code class="sourceCode default">N</code> objects or causes
the operation to fail (e.g., by throwing an exception or terminating the
program).</p>
<p>If Part I of this proposal is accepted, library authors might
implement a <code class="sourceCode default">small_vector</code>
template that supports relocate-only types. Such a
<code class="sourceCode default">small_vector</code> would itself be
relocate-only. Because a
<code class="sourceCode default">small_vector</code> stores its elements
inline, the relocation of a
<code class="sourceCode default">small_vector</code> object invalidates
all iterators into that object.</p>
<p>Consider now a struct <code class="sourceCode default">S</code> that
holds both a
<code class="sourceCode default">small_vector&lt;T&gt;</code> (where
<code class="sourceCode default">T</code> is a relocate-only type) and
an iterator into that
<code class="sourceCode default">small_vector&lt;T&gt;</code>.
<code class="sourceCode default">S</code> will not be trivially
relocatable, since the iterator member must be patched up during
relocation, nor will <code class="sourceCode default">S</code> have a
usable defaulted relocation constructor, since it is not movable (see
Section 4.2). The author of <code class="sourceCode default">S</code>
must implement a relocation constructor:</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">struct</span> S <span class="op">{</span></span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a>    small_vector<span class="op">&lt;</span>T<span class="op">&gt;</span>           d_v;</span>
<span id="cb20-3"><a href="#cb20-3" aria-hidden="true" tabindex="-1"></a>    small_vector<span class="op">&lt;</span>T<span class="op">&gt;::</span>iterator d_it;</span>
<span id="cb20-4"><a href="#cb20-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb20-5"><a href="#cb20-5" aria-hidden="true" tabindex="-1"></a>    S<span class="op">(</span><span class="kw">const</span> S<span class="op">&amp;)</span> <span class="op">=</span> <span class="kw">delete</span>;</span>
<span id="cb20-6"><a href="#cb20-6" aria-hidden="true" tabindex="-1"></a>    S<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">=(</span><span class="kw">const</span> S<span class="op">&amp;)</span> <span class="op">=</span> <span class="kw">delete</span>;</span>
<span id="cb20-7"><a href="#cb20-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb20-8"><a href="#cb20-8" aria-hidden="true" tabindex="-1"></a>    S<span class="op">(</span>S<span class="op">~</span> src<span class="op">)</span>;</span>
<span id="cb20-9"><a href="#cb20-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
<p>To relocate both <code class="sourceCode default">d_v</code> and
<code class="sourceCode default">d_it</code> correctly to the
destination object, the relocation constructor must compute the value
<code class="sourceCode default">d_it - d_v.begin()</code> (call it
<code class="sourceCode default">idx</code>) for the source object, and
then initialize the destination’s
<code class="sourceCode default">d_it</code> member with
<code class="sourceCode default">idx + d_v.begin()</code>. Because
<code class="sourceCode default">d_v</code> will be implicitly relocated
by the <em>ctor-initializer</em>, the computation of
<code class="sourceCode default">idx</code> cannot be deferred to the
<em>compound-statement</em> of the relocation constructor. It follows
that <code class="sourceCode default">S::S(S~)</code> needs to compute
<code class="sourceCode default">idx</code> and then immediately
delegate to another constructor that actually relocates
<code class="sourceCode default">d_v</code>:</p>
<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">struct</span> S <span class="op">{</span></span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a>    <span class="co">// other members previously described...</span></span>
<span id="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb21-4"><a href="#cb21-4" aria-hidden="true" tabindex="-1"></a>    S<span class="op">::</span>S<span class="op">(</span><span class="dt">size_t</span> idx, reloc S<span class="op">~</span> src<span class="op">)</span></span>
<span id="cb21-5"><a href="#cb21-5" aria-hidden="true" tabindex="-1"></a>      <span class="op">:</span> d_it<span class="op">(</span>d_v<span class="op">.</span>begin<span class="op">()</span> <span class="op">+</span> idx<span class="op">)</span> <span class="op">{}</span></span>
<span id="cb21-6"><a href="#cb21-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb21-7"><a href="#cb21-7" aria-hidden="true" tabindex="-1"></a>    S<span class="op">::</span>S<span class="op">(</span>S<span class="op">~</span> src<span class="op">)</span> <span class="op">:</span> S<span class="op">{</span>src<span class="op">.</span>d_it <span class="op">-</span> src<span class="op">.</span>d_v<span class="op">.</span>begin<span class="op">()</span>, reloc src<span class="op">}</span> <span class="op">{}</span></span>
<span id="cb21-8"><a href="#cb21-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>A number of features of the above implementation are noteworthy:</p>
<ul>
<li>When performing the delegation, we must use list-initialization
syntax because parenthesized initialization would fail to provide the
necessary sequencing guarantee to prevent
<code class="sourceCode default">src</code> from being accessed after
relocation (and would therefore be ill formed).</li>
<li>Similarly, the code above will not compile if the two-parameter
constructor has its parameters declared in the other order.</li>
<li>If the <code class="sourceCode default">reloc</code> specifier is
omitted for the two-parameter constructor, the compiler will attempt to
default-initialize <code class="sourceCode default">d_v</code> and then
destroy <code class="sourceCode default">src.d_v</code> at the end of
the <em>ctor-initializer</em>, which is unlikely to be the semantics the
programmer desired.</li>
<li>Thanks to the <code class="sourceCode default">reloc</code>
specifier, the construction of the
<code class="sourceCode default">d_v</code> member by relocation from
<code class="sourceCode default">src.d_v</code> is implicit. The
explicit <em>mem-initializer</em> for
<code class="sourceCode default">d_it</code> overrides the implicit
relocation that would otherwise occur for
<code class="sourceCode default">d_it</code>.</li>
</ul>
<p>We believe that such subtleties make user-provided relocation
constructors an expert-only feature, and even experts are likely to err.
The additional features that we propose in Part III will simplify the
implementation of <code class="sourceCode default">S</code> but at the
cost of further complexity in the language specification.</p>
<h1 data-number="6" id="part-iii-subordinate-references-and-delayed-initialization"><span class="header-section-number">6</span> Part III: Subordinate references
and delayed initialization<a href="#part-iii-subordinate-references-and-delayed-initialization" class="self-link"></a></h1>
<h2 data-number="6.1" id="motivation-for-delayed-initialization"><span class="header-section-number">6.1</span> Motivation for delayed
initialization<a href="#motivation-for-delayed-initialization" class="self-link"></a></h2>
<p>The example given in Part II for a class containing a small vector of
a relocate-only type can be rewritten much more simply if we introduce a
feature that allows the construction of bases and members of the
destination object to be deferred until some point in the
<em>compound-statement</em> of its constructor. We propose that such
deferred construction be performed by a new kind of statement called a
<em>delayed-ctor-initializer</em>, consisting of
<code class="sourceCode default">this :</code> and followed by a list of
<em>mem-initializers</em> and terminated by a semicolon:</p>
<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">struct</span> S <span class="op">{</span></span>
<span id="cb22-2"><a href="#cb22-2" aria-hidden="true" tabindex="-1"></a>    small_vector<span class="op">&lt;</span>T<span class="op">&gt;</span>           d_v;</span>
<span id="cb22-3"><a href="#cb22-3" aria-hidden="true" tabindex="-1"></a>    small_vector<span class="op">&lt;</span>T<span class="op">&gt;::</span>iterator d_it;</span>
<span id="cb22-4"><a href="#cb22-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb22-5"><a href="#cb22-5" aria-hidden="true" tabindex="-1"></a>    S<span class="op">(</span><span class="kw">const</span> S<span class="op">&amp;)</span> <span class="op">=</span> <span class="kw">delete</span>;</span>
<span id="cb22-6"><a href="#cb22-6" aria-hidden="true" tabindex="-1"></a>    S<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">=(</span><span class="kw">const</span> S<span class="op">&amp;)</span> <span class="op">=</span> <span class="kw">delete</span>;</span>
<span id="cb22-7"><a href="#cb22-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb22-8"><a href="#cb22-8" aria-hidden="true" tabindex="-1"></a>    S<span class="op">::</span>S<span class="op">(</span>reloc S<span class="op">~</span> src<span class="op">)</span> <span class="op">{</span></span>
<span id="cb22-9"><a href="#cb22-9" aria-hidden="true" tabindex="-1"></a>        <span class="kw">const</span> <span class="dt">size_t</span> idx <span class="op">=</span> src<span class="op">.</span>d_it <span class="op">-</span> src<span class="op">.</span>d_v<span class="op">.</span>begin<span class="op">()</span>;</span>
<span id="cb22-10"><a href="#cb22-10" aria-hidden="true" tabindex="-1"></a>        <span class="kw">this</span> <span class="op">:</span> d_it<span class="op">(</span>d_v<span class="op">.</span>begin<span class="op">()</span> <span class="op">+</span> idx<span class="op">)</span>;</span>
<span id="cb22-11"><a href="#cb22-11" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb22-12"><a href="#cb22-12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>When the definition of a constructor contains a
<em>delayed-ctor-initializer</em>, it shall not contain a
<em>ctor-initializer</em> and shall not implicitly initialize bases and
members prior to the constructor’s <em>compound-statement</em>.</p>
<p>Since C++11, no compelling need for
<em>delayed-ctor-initializers</em> in the language has arisen because
delegating constructors can be employed as an alternative. We believe
that the example from Part II, with its various gotchas, demonstrates a
case in which delegation is particularly difficult to use correctly and
difficult to read when used correctly due to the interaction of
delegation with owning references. Thus, we propose
<em>delayed-ctor-initializers</em> as part of this paper. Note that we
propose to allow <em>delayed-ctor-initializers</em> in all constructors,
not just relocation constructors. We believe that judicious use of
<em>delayed-ctor-initializers</em> can result in less error-prone
implementation of move constructors. (When programmers introduce a bug
related to evaluation order in delegating move constructors, they will
not receive a compile-time diagnostic as they would for a relocation
constructor like the one discussed in Part II, so although
<em>delayed-ctor-initializers</em> are important in supporting
user-defined relocation constructors, <em>delayed-ctor-initializers</em>
could end up being used more widely in move constructors than relocation
constructors.)</p>
<p>To define a constructor in which control flow can pass through more
than one <em>delayed-ctor-initializer</em> shall be a diagnosable error.
To be more specific, suppose a hypothetical owning reference variable
named <code class="sourceCode default">__r</code> were declared at the
very beginning of the constructor’s <em>compound-statement</em>, and
each <em>delayed-ctor-initializer</em> were replaced by
<code class="sourceCode default">reloc __r;</code>. The constructor is
ill formed if the transformed version would be ill formed due to
potentially referencing <code class="sourceCode default">__r</code> when
<code class="sourceCode default">__r</code> is disengaged. Any implicit
disengagement of <code class="sourceCode default">__r</code> and
destruction of its referent that would occur due to the rules about
owning references will instead result in the implicit execution of a
<em>delayed-ctor-initializer</em> of the form
<code class="sourceCode default">this : ;</code>.</p>
<h2 data-number="6.2" id="subordinate-references"><span class="header-section-number">6.2</span> Subordinate references<a href="#subordinate-references" class="self-link"></a></h2>
<p>The implicit relocation and disengagement semantics provided by the
<code class="sourceCode default">reloc</code> specifier might not always
be desired. In some cases, the programmer might wish for more explicit
control. Consider, for example, an <em>allocator-extended</em>
relocation constructor that does not use the allocator from the source
object but instead uses an allocator supplied by the caller. That
allocator must then be passed down to the allocator-extended relocation
constructors of any subobjects that use allocators:</p>
<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">using</span> allocator_type <span class="op">=</span> <span class="op">...</span>;</span>
<span id="cb23-2"><a href="#cb23-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb23-3"><a href="#cb23-3" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> S <span class="op">{</span></span>
<span id="cb23-4"><a href="#cb23-4" aria-hidden="true" tabindex="-1"></a>    allocator_type d_alloc;</span>
<span id="cb23-5"><a href="#cb23-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb23-6"><a href="#cb23-6" aria-hidden="true" tabindex="-1"></a>    S<span class="op">(</span>S<span class="op">~</span> src<span class="op">)</span>;</span>
<span id="cb23-7"><a href="#cb23-7" aria-hidden="true" tabindex="-1"></a>    S<span class="op">(</span>allocator_type alloc, S<span class="op">~</span> src<span class="op">)</span>;</span>
<span id="cb23-8"><a href="#cb23-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb23-9"><a href="#cb23-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb23-10"><a href="#cb23-10" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> T <span class="op">{</span></span>
<span id="cb23-11"><a href="#cb23-11" aria-hidden="true" tabindex="-1"></a>    allocator_type d_alloc;</span>
<span id="cb23-12"><a href="#cb23-12" aria-hidden="true" tabindex="-1"></a>    S              d_s;</span>
<span id="cb23-13"><a href="#cb23-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb23-14"><a href="#cb23-14" aria-hidden="true" tabindex="-1"></a>    T<span class="op">(</span>T<span class="op">~</span> src<span class="op">)</span>;</span>
<span id="cb23-15"><a href="#cb23-15" aria-hidden="true" tabindex="-1"></a>    T<span class="op">(</span>allocator_type alloc, T<span class="op">~</span> src<span class="op">)</span>;</span>
<span id="cb23-16"><a href="#cb23-16" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
<p>Implementing <code class="sourceCode default">T</code>’s
allocator-extended relocation constructor using the tools provided by
Part II is not possible because that constructor needs some way to
execute a <em>mem-initializer</em> resembling
<code class="sourceCode default">d_s(alloc, reloc src.d_s)</code>, but
<code class="sourceCode default">src.d_s</code> isn’t an
<em>id-expression</em>, so under the rules in Parts I and II,
<code class="sourceCode default">reloc src.d_s</code> is ill formed. As
we explained in Part II, such constructs are not permitted because they
make it impossible, in general, for the compiler to know which
subobjects of the source object must be prevented from being destroyed a
second time.</p>
<p>To allow this allocator-extended relocation constructor to be
implemented, we need to specify the meaning of
<code class="sourceCode default">reloc src.d_s</code>. The intuition
behind the semantics of such an expression is that
<code class="sourceCode default">reloc</code> acts upon an owning
reference with a known declaration, so
<code class="sourceCode default">src.d_s</code> must behave as if it
<em>names</em> an owning reference variable, even though
<code class="sourceCode default">src.d_s</code> is not one (nor could it
be, since owning references are not permitted as members). Furthermore,
if owning references are to exist to the subobjects of
<code class="sourceCode default">src</code>, then at the point where
such owning references exist, there must not be an owning reference to
the complete object that is still planning on destroying it, lest the
subobjects of <code class="sourceCode default">src</code> be destroyed
twice.</p>
<p>We must therefore have an operation that acts upon the owning
reference <code class="sourceCode default">src</code>, such that after
this operation has been executed,
<code class="sourceCode default">src</code> still refers to the same
object as it did before, and referring to
<code class="sourceCode default">src</code> is still well formed, but
<code class="sourceCode default">src</code> no longer intends to destroy
the object to which it refers. Such an owning reference is said to be
<em>under destruction</em>. We chose this name because the state of an
owning reference that is under destruction parallels the state of an
object whose destructor has begun execution (namely, its base and member
subobjects remain to be destroyed). The current “placeholder” syntax for
this operation is
<code class="sourceCode default">reloc_begin_destruction src</code>.
(The identifier
<code class="sourceCode default">reloc_begin_destruction</code> seems
unlikely to be have been used in real code but is unappealing; we hope
to propose a better syntax eventually.)</p>
<p>The allocator-extended relocation constructor described at the
beginning of this section can be implemented easily:</p>
<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">struct</span> T <span class="op">{</span></span>
<span id="cb24-2"><a href="#cb24-2" aria-hidden="true" tabindex="-1"></a>    allocator_type d_alloc;</span>
<span id="cb24-3"><a href="#cb24-3" aria-hidden="true" tabindex="-1"></a>    S              d_s;</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>    T<span class="op">(</span>T<span class="op">~</span> src<span class="op">)</span>;</span>
<span id="cb24-6"><a href="#cb24-6" aria-hidden="true" tabindex="-1"></a>    T<span class="op">(</span>allocator_type alloc, T<span class="op">~</span> src<span class="op">)</span> <span class="op">{</span></span>
<span id="cb24-7"><a href="#cb24-7" aria-hidden="true" tabindex="-1"></a>        reloc_begin_destruction src;</span>
<span id="cb24-8"><a href="#cb24-8" aria-hidden="true" tabindex="-1"></a>        <span class="kw">this</span> <span class="op">:</span> d_alloc<span class="op">(</span>alloc<span class="op">)</span>,</span>
<span id="cb24-9"><a href="#cb24-9" aria-hidden="true" tabindex="-1"></a>               d_s<span class="op">(</span>alloc, reloc src<span class="op">.</span>d_s<span class="op">)</span>;</span>
<span id="cb24-10"><a href="#cb24-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb24-11"><a href="#cb24-11" aria-hidden="true" tabindex="-1"></a>        <span class="co">// `src.d_s` goes out of scope and was already disengaged.</span></span>
<span id="cb24-12"><a href="#cb24-12" aria-hidden="true" tabindex="-1"></a>        <span class="co">// `src.d_alloc` goes out of scope and is destroyed.</span></span>
<span id="cb24-13"><a href="#cb24-13" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb24-14"><a href="#cb24-14" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
<p>The small vector example from the previous section can be rewritten
so that it employs explicit relocation instead of the
<code class="sourceCode default">reloc</code> specifier:</p>
<div class="sourceCode" id="cb25"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb25-1"><a href="#cb25-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> S <span class="op">{</span></span>
<span id="cb25-2"><a href="#cb25-2" aria-hidden="true" tabindex="-1"></a>    small_vector<span class="op">&lt;</span>T<span class="op">&gt;</span>           d_v;</span>
<span id="cb25-3"><a href="#cb25-3" aria-hidden="true" tabindex="-1"></a>    small_vector<span class="op">&lt;</span>T<span class="op">&gt;::</span>iterator d_it;</span>
<span id="cb25-4"><a href="#cb25-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb25-5"><a href="#cb25-5" aria-hidden="true" tabindex="-1"></a>    S<span class="op">(</span><span class="kw">const</span> S<span class="op">&amp;)</span> <span class="op">=</span> <span class="kw">delete</span>;</span>
<span id="cb25-6"><a href="#cb25-6" aria-hidden="true" tabindex="-1"></a>    S<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">=(</span><span class="kw">const</span> S<span class="op">&amp;)</span> <span class="op">=</span> <span class="kw">delete</span>;</span>
<span id="cb25-7"><a href="#cb25-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb25-8"><a href="#cb25-8" aria-hidden="true" tabindex="-1"></a>    S<span class="op">::</span>S<span class="op">(</span>S<span class="op">~</span> src<span class="op">)</span> <span class="op">{</span></span>
<span id="cb25-9"><a href="#cb25-9" aria-hidden="true" tabindex="-1"></a>        <span class="kw">const</span> <span class="dt">size_t</span> idx <span class="op">=</span> src<span class="op">.</span>d_it <span class="op">-</span> src<span class="op">.</span>d_v<span class="op">.</span>begin<span class="op">()</span>;</span>
<span id="cb25-10"><a href="#cb25-10" aria-hidden="true" tabindex="-1"></a>        reloc_begin_destruction src;</span>
<span id="cb25-11"><a href="#cb25-11" aria-hidden="true" tabindex="-1"></a>        <span class="kw">this</span> <span class="op">:</span> d_v<span class="op">(</span>reloc src<span class="op">.</span>d_v<span class="op">)</span>,</span>
<span id="cb25-12"><a href="#cb25-12" aria-hidden="true" tabindex="-1"></a>               d_it<span class="op">(</span>d_v<span class="op">.</span>begin<span class="op">()</span> <span class="op">+</span> idx<span class="op">)</span>;</span>
<span id="cb25-13"><a href="#cb25-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb25-14"><a href="#cb25-14" aria-hidden="true" tabindex="-1"></a>        <span class="co">// `src.d_it` goes out of scope and is destroyed.</span></span>
<span id="cb25-15"><a href="#cb25-15" aria-hidden="true" tabindex="-1"></a>        <span class="co">// `src.d_v` goes out of scope and was already disengaged.</span></span>
<span id="cb25-16"><a href="#cb25-16" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb25-17"><a href="#cb25-17" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Control flow that potentially calls
<code class="sourceCode default">reloc_begin_destruction</code> twice on
the same owning reference is ill formed. Essentially,
<code class="sourceCode default">reloc_begin_destruction r</code> is
permitted only if replacing all such evaluations for a given
<code class="sourceCode default">r</code> with
<code class="sourceCode default">reloc r</code> would not result in any
such invented <code class="sourceCode default">reloc r</code> violating
the rules on use of owning references after disengagement. Implicit
calls to <code class="sourceCode default">reloc_begin_destruction</code>
are inserted as necessary (in a manner similar to implicit
disengagements) to ensure that whether an owning reference is under
destruction at a particular point is statically known.</p>
<p><code class="sourceCode default">reloc_begin_destruction</code> is
permitted outside of a constructor but only if every nonstatic data
member, direct base class, and virtual base class of the operand would
be accessible at the point where
<code class="sourceCode default">reloc_begin_destruction</code>
occurs.</p>
<p><code class="sourceCode default">reloc_begin_destruction src</code>
must not only place <code class="sourceCode default">src.d_s</code>
under destruction, but also must initialize the <em>subordinate owning
references</em> <code class="sourceCode default">src.d_alloc</code> and
<code class="sourceCode default">src.d_s</code>. In general, there is
one such subordinate owning reference for each direct nonstatic data
member of object type and direct base class and one for each virtual
base class if <code class="sourceCode default">src</code> is not itself
a subordinate owning reference (i.e., it refers to a complete object).
These subordinate owning references are declared in the same order in
which the subobjects would be constructed so that when the subordinate
owning references go out of scope, they destroy the corresponding
subobjects in the same order in which the destructor of the complete
object would destroy them.</p>
<p>At a particular point in the constructor, if
<code class="sourceCode default">src</code> is under destruction, then a
member access expression naming a member of
<code class="sourceCode default">src</code>, whose left operand is the
<em>id-expression</em> <code class="sourceCode default">src</code>
(possibly parenthesized), is instead considered to name the subordinate
owning reference corresponding to the named member. If
<code class="sourceCode default">src</code> has a direct base class of
type <code class="sourceCode default">B</code>, the syntax
<code class="sourceCode default">static_cast&lt;B&amp;&gt;(src)</code>
names the subordinate owning reference corresponding to that base class
subobject. (The syntax is not
<code class="sourceCode default">static_cast&lt;B~&gt;(src)</code>
because the result is an lvalue; this is consistent with the idea that
the expression <em>names</em> an owning reference variable and that the
name of an owning reference variable is always an lvalue referring to
the owned object.)</p>
<div class="sourceCode" id="cb26"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb26-1"><a href="#cb26-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> S2 <span class="op">{</span></span>
<span id="cb26-2"><a href="#cb26-2" aria-hidden="true" tabindex="-1"></a>    std<span class="op">::</span>string d_s1;</span>
<span id="cb26-3"><a href="#cb26-3" aria-hidden="true" tabindex="-1"></a>    std<span class="op">::</span>string d_s2;</span>
<span id="cb26-4"><a href="#cb26-4" aria-hidden="true" tabindex="-1"></a>    std<span class="op">::</span>string d_s3 <span class="op">=</span> <span class="st">&quot;not used for this object yet&quot;</span>;</span>
<span id="cb26-5"><a href="#cb26-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb26-6"><a href="#cb26-6" aria-hidden="true" tabindex="-1"></a>    S2<span class="op">(</span>S2<span class="op">~</span> src<span class="op">)</span> <span class="op">{</span></span>
<span id="cb26-7"><a href="#cb26-7" aria-hidden="true" tabindex="-1"></a>        reloc_begin_destruction src;</span>
<span id="cb26-8"><a href="#cb26-8" aria-hidden="true" tabindex="-1"></a>            <span class="co">// declares subordinate references to `src.d_s1`, `src.d_s2`, and</span></span>
<span id="cb26-9"><a href="#cb26-9" aria-hidden="true" tabindex="-1"></a>            <span class="co">// `src.d_s3`, in that order;</span></span>
<span id="cb26-10"><a href="#cb26-10" aria-hidden="true" tabindex="-1"></a>            <span class="co">// `src` is now under destruction</span></span>
<span id="cb26-11"><a href="#cb26-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb26-12"><a href="#cb26-12" aria-hidden="true" tabindex="-1"></a>        <span class="kw">this</span> <span class="op">:</span> d_s1<span class="op">(</span>reloc src<span class="op">.</span>d_s1<span class="op">)</span></span>
<span id="cb26-13"><a href="#cb26-13" aria-hidden="true" tabindex="-1"></a>               <span class="co">// disengages subordinate reference to `src.d_s1`</span></span>
<span id="cb26-14"><a href="#cb26-14" aria-hidden="true" tabindex="-1"></a>             , d_s2<span class="op">(</span>reloc src<span class="op">.</span>d_s2<span class="op">)</span></span>
<span id="cb26-15"><a href="#cb26-15" aria-hidden="true" tabindex="-1"></a>               <span class="co">// disengages subordinate reference to `src.d_s2`</span></span>
<span id="cb26-16"><a href="#cb26-16" aria-hidden="true" tabindex="-1"></a>             ;</span>
<span id="cb26-17"><a href="#cb26-17" aria-hidden="true" tabindex="-1"></a>               <span class="co">// initializes `d_s3` using its default member initializer</span></span>
<span id="cb26-18"><a href="#cb26-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb26-19"><a href="#cb26-19" aria-hidden="true" tabindex="-1"></a>        std<span class="op">::</span>cout <span class="op">&lt;&lt;</span> src<span class="op">.</span>d_s1<span class="op">.</span>size<span class="op">()</span>;</span>
<span id="cb26-20"><a href="#cb26-20" aria-hidden="true" tabindex="-1"></a>            <span class="co">// Ill formed: src.d_s1 names subordinate reference,</span></span>
<span id="cb26-21"><a href="#cb26-21" aria-hidden="true" tabindex="-1"></a>            <span class="co">// which is disengaged.</span></span>
<span id="cb26-22"><a href="#cb26-22" aria-hidden="true" tabindex="-1"></a>        std<span class="op">::</span>cout <span class="op">&lt;&lt;</span> src<span class="op">.</span>d_s3<span class="op">.</span>size<span class="op">()</span>;</span>
<span id="cb26-23"><a href="#cb26-23" aria-hidden="true" tabindex="-1"></a>            <span class="co">// OK</span></span>
<span id="cb26-24"><a href="#cb26-24" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb26-25"><a href="#cb26-25" aria-hidden="true" tabindex="-1"></a>        <span class="co">// Subordinate reference to `src.d_s3` goes out of scope and</span></span>
<span id="cb26-26"><a href="#cb26-26" aria-hidden="true" tabindex="-1"></a>        <span class="co">// destroys `src.d_s3`.</span></span>
<span id="cb26-27"><a href="#cb26-27" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb26-28"><a href="#cb26-28" aria-hidden="true" tabindex="-1"></a>        <span class="co">// Subordinate reference to `src.d_s2` goes out of scope and is</span></span>
<span id="cb26-29"><a href="#cb26-29" aria-hidden="true" tabindex="-1"></a>        <span class="co">// already disengaged.</span></span>
<span id="cb26-30"><a href="#cb26-30" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb26-31"><a href="#cb26-31" aria-hidden="true" tabindex="-1"></a>        <span class="co">// Subordinate reference to `src.d_s1` goes out of scope and is</span></span>
<span id="cb26-32"><a href="#cb26-32" aria-hidden="true" tabindex="-1"></a>        <span class="co">// already disengaged.</span></span>
<span id="cb26-33"><a href="#cb26-33" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb26-34"><a href="#cb26-34" aria-hidden="true" tabindex="-1"></a>        <span class="co">// `src` goes out of scope, but it is under destruction so it does</span></span>
<span id="cb26-35"><a href="#cb26-35" aria-hidden="true" tabindex="-1"></a>        <span class="co">// not call `src.~S()`.</span></span>
<span id="cb26-36"><a href="#cb26-36" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb26-37"><a href="#cb26-37" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
<p>The meaning of <code class="sourceCode default">src.d_s</code>
depends on whether <code class="sourceCode default">src</code> is under
destruction, so performing a member access through
<code class="sourceCode default">src</code> at a point where control
flow is ambiguous as to whether
<code class="sourceCode default">reloc_begin_destruction src</code> has
been evaluated is ill formed.</p>
<p>When a constructor containing a <em>delayed-ctor-initializer</em>
also has a parameter that bears the
<code class="sourceCode default">reloc</code> specifier, the implicit
relocation and destruction semantics of the
<code class="sourceCode default">reloc</code> specifier do not go into
effect until the <em>delayed-ctor-initializer</em> is executed.</p>
<div class="sourceCode" id="cb27"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb27-1"><a href="#cb27-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> S1 <span class="op">{</span></span>
<span id="cb27-2"><a href="#cb27-2" aria-hidden="true" tabindex="-1"></a>    T d_foo;</span>
<span id="cb27-3"><a href="#cb27-3" aria-hidden="true" tabindex="-1"></a>    T d_bar;</span>
<span id="cb27-4"><a href="#cb27-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb27-5"><a href="#cb27-5" aria-hidden="true" tabindex="-1"></a>    S1<span class="op">(</span>S1<span class="op">~</span> source<span class="op">)</span> <span class="op">{</span></span>
<span id="cb27-6"><a href="#cb27-6" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">(</span>rand<span class="op">()</span> <span class="op">%</span> <span class="dv">2</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb27-7"><a href="#cb27-7" aria-hidden="true" tabindex="-1"></a>            reloc_begin_destruction source;</span>
<span id="cb27-8"><a href="#cb27-8" aria-hidden="true" tabindex="-1"></a>            <span class="kw">this</span> <span class="op">:</span> d_foo<span class="op">(</span>source<span class="op">.</span>d_foo<span class="op">)</span>,</span>
<span id="cb27-9"><a href="#cb27-9" aria-hidden="true" tabindex="-1"></a>                   d_bar<span class="op">(</span><span class="dv">0</span><span class="op">)</span>;</span>
<span id="cb27-10"><a href="#cb27-10" aria-hidden="true" tabindex="-1"></a>            <span class="co">// `source.d_foo` may no longer be referenced;</span></span>
<span id="cb27-11"><a href="#cb27-11" aria-hidden="true" tabindex="-1"></a>            <span class="co">// `source.d_bar` may still be referenced.</span></span>
<span id="cb27-12"><a href="#cb27-12" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb27-13"><a href="#cb27-13" aria-hidden="true" tabindex="-1"></a>        <span class="co">// implicitly:</span></span>
<span id="cb27-14"><a href="#cb27-14" aria-hidden="true" tabindex="-1"></a>        <span class="co">// else {</span></span>
<span id="cb27-15"><a href="#cb27-15" aria-hidden="true" tabindex="-1"></a>        <span class="co">//     reloc_begin_destruction source;</span></span>
<span id="cb27-16"><a href="#cb27-16" aria-hidden="true" tabindex="-1"></a>        <span class="co">//     this : ;</span></span>
<span id="cb27-17"><a href="#cb27-17" aria-hidden="true" tabindex="-1"></a>        <span class="co">// }</span></span>
<span id="cb27-18"><a href="#cb27-18" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb27-19"><a href="#cb27-19" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb27-20"><a href="#cb27-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb27-21"><a href="#cb27-21" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> S2 <span class="op">{</span></span>
<span id="cb27-22"><a href="#cb27-22" aria-hidden="true" tabindex="-1"></a>    T d_foo;</span>
<span id="cb27-23"><a href="#cb27-23" aria-hidden="true" tabindex="-1"></a>    T d_bar;</span>
<span id="cb27-24"><a href="#cb27-24" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb27-25"><a href="#cb27-25" aria-hidden="true" tabindex="-1"></a>    S2<span class="op">(</span>reloc S2<span class="op">~</span> source<span class="op">)</span> <span class="op">{</span></span>
<span id="cb27-26"><a href="#cb27-26" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">(</span>rand<span class="op">()</span> <span class="op">%</span> <span class="dv">2</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb27-27"><a href="#cb27-27" aria-hidden="true" tabindex="-1"></a>            <span class="kw">this</span> <span class="op">:</span> d_bar<span class="op">(</span><span class="dv">0</span><span class="op">)</span>;</span>
<span id="cb27-28"><a href="#cb27-28" aria-hidden="true" tabindex="-1"></a>            <span class="co">// `d_foo` is implicitly initialized by relocation;</span></span>
<span id="cb27-29"><a href="#cb27-29" aria-hidden="true" tabindex="-1"></a>            <span class="co">// `source.d_foo` is destroyed by `T`&#39;s relocation constructor</span></span>
<span id="cb27-30"><a href="#cb27-30" aria-hidden="true" tabindex="-1"></a>            <span class="co">// while `source.d_bar` is implicitly destroyed;</span></span>
<span id="cb27-31"><a href="#cb27-31" aria-hidden="true" tabindex="-1"></a>            <span class="co">// `std::disengage(reloc source)` is called implicitly.</span></span>
<span id="cb27-32"><a href="#cb27-32" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb27-33"><a href="#cb27-33" aria-hidden="true" tabindex="-1"></a>        <span class="co">// implicitly:</span></span>
<span id="cb27-34"><a href="#cb27-34" aria-hidden="true" tabindex="-1"></a>        <span class="co">// else {</span></span>
<span id="cb27-35"><a href="#cb27-35" aria-hidden="true" tabindex="-1"></a>        <span class="co">//     this : ;</span></span>
<span id="cb27-36"><a href="#cb27-36" aria-hidden="true" tabindex="-1"></a>        <span class="co">// }</span></span>
<span id="cb27-37"><a href="#cb27-37" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb27-38"><a href="#cb27-38" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Evaluating
<code class="sourceCode default">reloc_begin_destruction</code> for an
owning reference parameter that is declared with the
<code class="sourceCode default">reloc</code> specifier is ill formed.
(The <code class="sourceCode default">reloc</code> specifier, described
in Part II, implicitly performs a function that is very similar to
<code class="sourceCode default">reloc_begin_destruction</code> prior to
entering the <em>ctor-initializer</em>. However, note that the implicit
destruction semantics afforded by the
<code class="sourceCode default">reloc</code> specifier will destroy
subobjects of the source object in the opposite order from the source
object’s destructor, while the subordinate references declared by
<code class="sourceCode default">reloc_begin_destruction</code> will go
out of scope in the same order as their corresponding subobjects would
be destroyed by the source object’s destructor.)</p>
<h2 data-number="6.3" id="explicit-owning-reference-to-self-for-destructors"><span class="header-section-number">6.3</span> Explicit owning reference to
self for destructors<a href="#explicit-owning-reference-to-self-for-destructors" class="self-link"></a></h2>
<p>We propose that the syntax
<code class="sourceCode default">~T(this T~ self)</code> be permitted
for declaring a destructor. Note that destructors are currently not
permitted to use explicit object parameter syntax; e.g.,
<code class="sourceCode default">~T(this T&amp; self)</code> is not
permitted. We propose to permit a destructor to use explicit object
parameter syntax solely in the case where the parameter is an owning
reference to the class type to which the destructor belongs.</p>
<p>In a destructor so declared,
<code class="sourceCode default">reloc_begin_destruction self</code> is
implicitly executed at the beginning of the destructor’s
<em>compound-statement</em>, and an <em>id-expression</em> naming a
direct member of the destructor’s class implicitly names a subordinate
owning reference. That is, if <code class="sourceCode default">m</code>
is a direct member of the destructor’s class, either
<code class="sourceCode default">m</code> or
<code class="sourceCode default">self.m</code> can be used to name the
subordinate owning reference. The syntax <code class="sourceCode default">static_cast&lt;Base&amp;&gt;(self)</code>
must be used to name the subordinate owning reference corresponding to a
direct base class subobject of type
<code class="sourceCode default">Base</code>.</p>
<p>The motivation for such destructor declarations is to permit a
destructor to return a resource to a pool by relocation, where that
resource is owned by a member of the destructor’s class:</p>
<div class="sourceCode" id="cb28"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb28-1"><a href="#cb28-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> S <span class="op">{</span></span>
<span id="cb28-2"><a href="#cb28-2" aria-hidden="true" tabindex="-1"></a>    relocate_ptr<span class="op">&lt;</span>Resource<span class="op">&gt;</span> d_resource;</span>
<span id="cb28-3"><a href="#cb28-3" aria-hidden="true" tabindex="-1"></a>    ResourcePool<span class="op">*</span>          d_pool;</span>
<span id="cb28-4"><a href="#cb28-4" aria-hidden="true" tabindex="-1"></a>    std<span class="op">::</span>string            d_name;</span>
<span id="cb28-5"><a href="#cb28-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb28-6"><a href="#cb28-6" aria-hidden="true" tabindex="-1"></a>    <span class="op">~</span>S<span class="op">(</span><span class="kw">this</span> S<span class="op">~</span> self<span class="op">)</span> <span class="op">{</span></span>
<span id="cb28-7"><a href="#cb28-7" aria-hidden="true" tabindex="-1"></a>        <span class="co">// `reloc_begin_destruction self` is executed implicitly.</span></span>
<span id="cb28-8"><a href="#cb28-8" aria-hidden="true" tabindex="-1"></a>        d_pool<span class="op">-&gt;</span><span class="cf">return</span><span class="op">(</span>reloc d_resource<span class="op">)</span>;</span>
<span id="cb28-9"><a href="#cb28-9" aria-hidden="true" tabindex="-1"></a>            <span class="co">// `d_resource` is equivalent to `self.d_resource`.</span></span>
<span id="cb28-10"><a href="#cb28-10" aria-hidden="true" tabindex="-1"></a>            <span class="co">// `d_pool` takes ownership of subordinate owning reference.</span></span>
<span id="cb28-11"><a href="#cb28-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb28-12"><a href="#cb28-12" aria-hidden="true" tabindex="-1"></a>        <span class="co">// Subordinate owning reference corresponding to `d_name` goes out of scope</span></span>
<span id="cb28-13"><a href="#cb28-13" aria-hidden="true" tabindex="-1"></a>        <span class="co">// and destroys `d_name`.</span></span>
<span id="cb28-14"><a href="#cb28-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb28-15"><a href="#cb28-15" aria-hidden="true" tabindex="-1"></a>        <span class="co">// Subordinate owning reference corresponding to `d_pool` goes out of scope.</span></span>
<span id="cb28-16"><a href="#cb28-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb28-17"><a href="#cb28-17" aria-hidden="true" tabindex="-1"></a>        <span class="co">// Subordinate owning reference corresponding to `d_resource` is already disengaged.</span></span>
<span id="cb28-18"><a href="#cb28-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb28-19"><a href="#cb28-19" aria-hidden="true" tabindex="-1"></a>        <span class="co">// `self` is under destruction, so it does not attempt to re-destroy the</span></span>
<span id="cb28-20"><a href="#cb28-20" aria-hidden="true" tabindex="-1"></a>        <span class="co">// object to which it refers.</span></span>
<span id="cb28-21"><a href="#cb28-21" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb28-22"><a href="#cb28-22" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
<p>Our reason for proposing to make this feature available only in the
presence of an explicit object parameter is to avoid giving special
meaning to the expression <code class="sourceCode default">*this</code>,
which would need to be evaluated to name a subordinate owning reference
to a base class subobject — i.e., as part of the expression <code class="sourceCode default">static_cast&lt;Base&amp;&gt;(*this)</code>.
Since <code class="sourceCode default">*this</code> is not an
<em>id-expression</em>, for
<code class="sourceCode default">*this</code> (but not a more complex
expression) to be usable for naming subordinate owning references would
be counterintuitive.</p>
<p>All destructors that have such an explicit object parameter of owning
reference type are considered prospective (just like destructors with no
parameters) until the end of the class definition. Overload resolution
is then performed among all destructors that have an explicit object
parameter to select the one that is the most constrained. If both a
selected destructor with no parameters and a selected destructor with an
explicit owning reference parameter are present, the class definition is
ill formed. If the selected destructor has an explicit owning reference
parameter, any (explicit or implicit) call to that destructor implicitly
applies <code class="sourceCode default">reloc</code>, as necessary, to
initialize the destructor’s parameter.</p>
<h1 data-number="7" id="comparison-with-other-relocation-proposals"><span class="header-section-number">7</span> Comparison with other relocation
proposals<a href="#comparison-with-other-relocation-proposals" class="self-link"></a></h1>
<p>WG21 members have created many proposals for relocation in C++. We
will first discuss the other known proposals for <em>nontrivial</em>
relocation and explain why we are proposing the introduction of owning
references while the other nontrivial relocation proposals make do
without them. Afterward, we will discuss the interaction of our proposal
with the two most recent <em>trivial</em> relocation proposals, which
are known to be actively pursued by their authors.</p>
<h2 data-number="7.1" id="d2785"><span class="header-section-number">7.1</span> D2785<a href="#d2785" class="self-link"></a></h2>
<p><span class="citation" data-cites="D2785">[<a href="#ref-D2785" role="doc-biblioref">D2785</a>]</span> is most similar to our proposal
and introduces no additional types but does introduce a new kind of
prvalue obtained from relocating a glvalue: a prvalue that already has
storage backing it (as opposed to one that will construct an object into
the storage determined by the context). In effect, D2785 also proposes a
new value category but does not propose a generalized vocabulary for
manipulating expressions of this value category. The type
<code class="sourceCode default">T~</code> in our proposal is a
reification of the fourth value category, just as
<code class="sourceCode default">T&amp;&amp;</code> is a reification of
the xvalue category that was introduced in C++11.</p>
<p>We believe that the introduction of the rlvalue category — and of
owning reference types that may bind to them — results in a conceptually
simpler model than the model of D2785.</p>
<p>Owning references also provide practical benefits. Because an owning
reference can be perfectly forwarded with only the runtime cost of
copying a pointer and the actual relocation only occurs at the end of
this process, our approach never requires intermediate relocations when
multiple function calls intervene between the scope in which a source
object is declared and the scope in which a destination object is
constructed by relocation from that source object:</p>
<div class="sourceCode" id="cb29"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb29-1"><a href="#cb29-1" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> consume<span class="op">(</span>T t<span class="op">)</span>;</span>
<span id="cb29-2"><a href="#cb29-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb29-3"><a href="#cb29-3" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> logAndConsume<span class="op">(</span>T<span class="op">~</span> r<span class="op">)</span> <span class="op">{</span></span>
<span id="cb29-4"><a href="#cb29-4" aria-hidden="true" tabindex="-1"></a>    std<span class="op">::</span>cout <span class="op">&lt;&lt;</span> <span class="st">&quot;Eating: &quot;</span> <span class="op">&lt;&lt;</span> <span class="op">&amp;</span>r <span class="op">&lt;&lt;</span> std<span class="op">::</span>endl;</span>
<span id="cb29-5"><a href="#cb29-5" aria-hidden="true" tabindex="-1"></a>    consume<span class="op">(</span>reloc r<span class="op">)</span>;  <span class="co">// calls relocation constructor</span></span>
<span id="cb29-6"><a href="#cb29-6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb29-7"><a href="#cb29-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb29-8"><a href="#cb29-8" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> f<span class="op">()</span> <span class="op">{</span></span>
<span id="cb29-9"><a href="#cb29-9" aria-hidden="true" tabindex="-1"></a>    T src;</span>
<span id="cb29-10"><a href="#cb29-10" aria-hidden="true" tabindex="-1"></a>    logAndConsume<span class="op">(</span>reloc src<span class="op">)</span>;</span>
<span id="cb29-11"><a href="#cb29-11" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Functions with <code class="sourceCode default">T~</code> parameters
in our approach are expected to be declared with parameters of type
<code class="sourceCode default">T</code> in the D2785 approach:</p>
<div class="sourceCode" id="cb30"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb30-1"><a href="#cb30-1" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> consume<span class="op">(</span>T t<span class="op">)</span>;</span>
<span id="cb30-2"><a href="#cb30-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb30-3"><a href="#cb30-3" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> logAndConsume<span class="op">(</span>T r<span class="op">)</span> <span class="op">{</span></span>
<span id="cb30-4"><a href="#cb30-4" aria-hidden="true" tabindex="-1"></a>    std<span class="op">::</span>cout <span class="op">&lt;&lt;</span> <span class="st">&quot;Eating: &quot;</span> <span class="op">&lt;&lt;</span> <span class="op">&amp;</span>r <span class="op">&lt;&lt;</span> std<span class="op">::</span>endl;</span>
<span id="cb30-5"><a href="#cb30-5" aria-hidden="true" tabindex="-1"></a>    consume<span class="op">(</span>reloc r<span class="op">)</span>;  <span class="co">// calls relocation constructor</span></span>
<span id="cb30-6"><a href="#cb30-6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb30-7"><a href="#cb30-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb30-8"><a href="#cb30-8" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> f<span class="op">()</span> <span class="op">{</span></span>
<span id="cb30-9"><a href="#cb30-9" aria-hidden="true" tabindex="-1"></a>    T src;</span>
<span id="cb30-10"><a href="#cb30-10" aria-hidden="true" tabindex="-1"></a>    logAndConsume<span class="op">(</span>reloc src<span class="op">)</span>;  <span class="co">// may call relocation constructor</span></span>
<span id="cb30-11"><a href="#cb30-11" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>In the above snippet, the creation of a new
<code class="sourceCode default">T</code> object named
<code class="sourceCode default">r</code> when calling
<code class="sourceCode default">logAndConsume</code> can be elided if
that function is inlined or if that function is given an ABI in which
the <code class="sourceCode default">T</code> parameter is implicitly
passed by reference, which is not possible in general. (The
implementation decision to use such an ABI would necessarily affect
<em>all</em> functions with the same signature as
<code class="sourceCode default">logAndConsume</code>.) Giving users the
ability to explicitly declare parameters to have type
<code class="sourceCode default">T~</code> gives them a way to select
which ABI they want and also avoids the issue in the D2785 approach
wherein the value of <code class="sourceCode default">&amp;r</code>
depends on whether <code class="sourceCode default">r</code> has been
elided by the implementation.</p>
<h2 data-number="7.2" id="n4158"><span class="header-section-number">7.2</span> N4158<a href="#n4158" class="self-link"></a></h2>
<p>The fundamental relocation operation in <span class="citation" data-cites="N4158">[<a href="#ref-N4158" role="doc-biblioref">N4158</a>]</span> is a call to a customization
point called
<code class="sourceCode default">uninitialized_destructive_move</code>,
which takes two pointer arguments called
<code class="sourceCode default">from</code> and
<code class="sourceCode default">to</code> and constructs an object at
<code class="sourceCode default">to</code> having the value held by
<code class="sourceCode default">*from</code> while also ending the
lifetime of <code class="sourceCode default">*from</code>.</p>
<p>A pure library facility such as that proposed by N4158 cannot be used
to relocate automatic variables because the call to
<code class="sourceCode default">uninitialized_destructive_move</code>
does not suppress the implicit destructor call when the variable goes
out of scope. Therefore, the N4158 approach is necessarily
pointer-based, while our approach is value-based and enables a natural
coding style where objects that are to be relocated can be declared as
local variables of object type.</p>
<p>In N4158, a programmer can avoid heap allocation for objects that are
to be relocated by constructing them into a stack buffer but must then
ensure that if the relocation actually occurs, the object is not
thereafter accessed, and that if the relocation does not occur, the
object’s destructor is eventually called to release any resources owned
by the object. In our approach, by declaring the object as an automatic
variable, the necessary guarantees are provided by the compiler. Our
approach is therefore safer than N4158 because, by making most such
accesses ill formed, it prevents accidental access to objects that might
have been relocated from. (However, we are not proposing a borrow
checker for C++; an lvalue reference to a local variable that is then
relocated from can still be used to attempt to perform an access of that
variable, resulting in undefined behavior.)</p>
<p>The N4158 approach encourages the programmer to pass the source
object by pointer until the point at which the relocation will actually
occur; doing so avoids unnecessary intermediate relocations, but the
<em>intent to relocate</em> cannot be perfectly forwarded when the
source pointer is passed, since it will appear to a factory function as
just a pointer, and the factory function will pass that pointer to a
constructor rather than calling
<code class="sourceCode default">uninitialized_destructive_move</code>.
In our approach, rlvalues can be perfectly forwarded by functions that
have a forwarding reference parameter spelled
<code class="sourceCode default">T~</code>, and no additional machinery
is required.</p>
<p>The
<code class="sourceCode default">uninitialized_destructive_move</code>
function proposed by N4158 could be implemented as follows under our
proposal:</p>
<div class="sourceCode" id="cb31"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb31-1"><a href="#cb31-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>
<span id="cb31-2"><a href="#cb31-2" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> uninitialized_destructive_move<span class="op">(</span>T<span class="op">*</span> from, T<span class="op">*</span> to<span class="op">)</span> <span class="op">{</span></span>
<span id="cb31-3"><a href="#cb31-3" aria-hidden="true" tabindex="-1"></a>    <span class="op">::</span><span class="kw">new</span> <span class="op">(</span><span class="kw">static_cast</span><span class="op">&lt;</span><span class="dt">void</span><span class="op">*&gt;(</span>to<span class="op">))</span> T<span class="op">(</span><span class="kw">static_cast</span><span class="op">&lt;</span>T<span class="op">~&gt;(*</span>from<span class="op">))</span>;</span>
<span id="cb31-4"><a href="#cb31-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Note that customization of the functionality of the implementation
shown above would be accomplished by customizing the relocation
constructor of <code class="sourceCode default">T</code>, not by
declaring an overload. Also note that because our proposal specifies a
move-and-destroy fallback behavior for defaulted move constructors, we
need not explicitly specify such fallback behavior for the <code class="sourceCode default">std::uninitialized_destructive_move</code>
function template.</p>
<h2 data-number="7.3" id="p0023"><span class="header-section-number">7.3</span> P0023<a href="#p0023" class="self-link"></a></h2>
<p><span class="citation" data-cites="P0023R0">[<a href="#ref-P0023R0" role="doc-biblioref">P0023R0</a>]</span> uses the syntax
<code class="sourceCode default">new (dest) &gt;&gt;T(*src)</code> to
construct a <code class="sourceCode default">T</code> object at
<code class="sourceCode default">dest</code> having the value held by
<code class="sourceCode default">*src</code>. The actual relocation is
performed by a function called a <em>relocator</em>, introduced in the
scope of <code class="sourceCode default">T</code> by a declarator of
the form <code class="sourceCode default">&gt;&gt;T(T&amp; src)</code>.
Despite looking very different from N4158, P0023 has similar
limitations; it cannot be used to safely relocate objects with automatic
storage duration, does not prevent use-after-relocation, and does not
provide a facility for perfectly forwarding the intent to evaluate
<code class="sourceCode default">new (dest) &gt;&gt;T(*src)</code>
instead of <code class="sourceCode default">new (dest) T(src)</code>,
where <code class="sourceCode default">src</code> is an argument of
pointer type.</p>
<h2 data-number="7.4" id="p1144r7-and-p2786r0"><span class="header-section-number">7.4</span> P1144R7 and P2786R0<a href="#p1144r7-and-p2786r0" class="self-link"></a></h2>
<p><span class="citation" data-cites="P1144R7">[<a href="#ref-P1144R7" role="doc-biblioref">P1144R7</a>]</span> and <span class="citation" data-cites="P2786R0">[<a href="#ref-P2786R0" role="doc-biblioref">P2786R0</a>]</span> are similar proposals.</p>
<ul>
<li>They each introduce the concept of trivial relocatability, in which
some types are <em>implicitly</em> trivially relocatable, but the author
of a class can also explicitly declare that class to be trivially
relocatable even if it has nontrivial special member functions.</li>
<li>They each provide library facilities, known as
<code class="sourceCode default">std::relocate</code> and
<code class="sourceCode default">std::relocate_at</code>, that take a
pair of pointers to <code class="sourceCode default">T</code> and either
perform trivial relocation (when
<code class="sourceCode default">T</code> is trivially relocatable) or
destroy the source object after move-constructing the destination
object. Such library facilities can be used to speed up operations that
are currently expressed exclusively in terms of move plus destroy, e.g.,
the operation of relocating elements of
<code class="sourceCode default">std::vector&lt;T&gt;</code> when the
vector’s capacity is increased.</li>
</ul>
<p>The definition of the category of implicitly trivially relocatable
types differs slightly between P1144R7 and P2786R0. We do not express an
opinion on which definition should be chosen; debate in EWG should
resolve this question, and the authors of P1144R7 and P2786R0 are well
positioned to argue their respective cases. The same is true for the
syntax and semantics of explicitly declaring a class type to be
trivially relocatable, which also differ between P1144R7 and P2786R0.
Our proposal can build upon the trivial relocatability machinery of
either P1144R7 or P2786R0. (Clearly, a class with a
<em>user-provided</em> relocation constructor — see Part II — will not
be trivially relocatable and a diagnostic should be required if the
programmer attempts to declare the class to be trivially
relocatable.)</p>
<p>Because P1144R7 and P2786R0 both employ pointer-based approaches to
performing relocation, they suffer from the same limitations as N4158
and P0023 with respect to automatic variables. Nevertheless, the use of
such pointer-based interfaces for relocating objects of dynamic storage
duration is compatible with our proposal. For example, if P1144R7 is
accepted, our proposal will be to modify the specification of
<code class="sourceCode default">std::relocate_at</code> so that when
<code class="sourceCode default">T</code> is not trivially relocatable
but has a usable relocation constructor, that constructor will be called
in preference to performing a move-and-destroy operation.</p>
<h2 data-number="7.5" id="p1029r3"><span class="header-section-number">7.5</span> P1029R3<a href="#p1029r3" class="self-link"></a></h2>
<p><span class="citation" data-cites="P1029R3">[<a href="#ref-P1029R3" role="doc-biblioref">P1029R3</a>]</span> proposed a pure core language
extension to define a move constructor as performing a bitwise copy from
source to destination, followed by resetting the source object by
copying into it the bit pattern that would be produced by its default
constructor (which is required to be
<code class="sourceCode default">constexpr</code>).</p>
<p>P1029R3 was made deliberately minimal to have the best possible
chance of being adopted into C++23, and its author is no longer pursuing
it. In particular, P1029R3 offers no form of nontrivial relocation.</p>
<p>Our proposal offers the semantics of a P1029R3-style relocation:</p>
<div class="sourceCode" id="cb32"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb32-1"><a href="#cb32-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="dt">int</span> <span class="op">=</span> <span class="op">(</span>T<span class="op">()</span>, <span class="dv">0</span><span class="op">)&gt;</span></span>
<span id="cb32-2"><a href="#cb32-2" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> P1029R3_relocate<span class="op">(</span>T<span class="op">*</span> from, T<span class="op">*</span> to<span class="op">)</span></span>
<span id="cb32-3"><a href="#cb32-3" aria-hidden="true" tabindex="-1"></a><span class="kw">requires</span> std<span class="op">::</span>is_trivially_relocatable_v<span class="op">&lt;</span>T<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb32-4"><a href="#cb32-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">static</span> <span class="kw">constexpr</span> T zero;</span>
<span id="cb32-5"><a href="#cb32-5" aria-hidden="true" tabindex="-1"></a>    std<span class="op">::</span>memcpy<span class="op">(</span>to, from, <span class="kw">sizeof</span><span class="op">(</span>T<span class="op">))</span>;</span>
<span id="cb32-6"><a href="#cb32-6" aria-hidden="true" tabindex="-1"></a>    std<span class="op">::</span>memcpy<span class="op">(</span>from, <span class="op">&amp;</span>zero, <span class="kw">sizeof</span><span class="op">(</span>T<span class="op">))</span>;</span>
<span id="cb32-7"><a href="#cb32-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<h1 data-number="8" id="appendix-a-potentially-breaking-changes"><span class="header-section-number">8</span> Appendix A: Potentially breaking
changes<a href="#appendix-a-potentially-breaking-changes" class="self-link"></a></h1>
<ul>
<li><code class="sourceCode default">x.~T()</code>, where
<code class="sourceCode default">x</code> is an automatic variable of
type <code class="sourceCode default">T</code>, can also disengage
<code class="sourceCode default">__x~</code>. This rule would make
naming <code class="sourceCode default">x</code> after this line ill
formed, unless and until a placement new expression is used to recreate
<code class="sourceCode default">x</code>. This rule would also break
some existing code but potentially increase safety by preventing access
to a variable whose lifetime has ended. Specifying this rule would be
painful: We would need to define the class of expressions we consider to
be placement new expressions for the purposes of this rule, and we would
also need to introduce another set of control flow rules. (The control
flow rules for Part I assume that owning references can be disengaged
along some paths of control flow; here, we would need rules that account
for owning references being able to become re-engaged.)</li>
<li>Require callee-destroy for all by-value function parameters, which
would allow <code class="sourceCode default">reloc</code> to be applied
to function parameters.</li>
</ul>
<h1 data-number="9" id="appendix-b-alternative-syntaxes-for-forwarding-references"><span class="header-section-number">9</span> Appendix B: Alternative syntaxes
for forwarding references<a href="#appendix-b-alternative-syntaxes-for-forwarding-references" class="self-link"></a></h1>
<p>We considered three possible approaches to perfectly forwarding
owning references. We propose the first approach below but are open to
polling to determine the best choice.</p>
<h2 data-number="9.1" id="t-syntax"><span class="header-section-number">9.1</span>
<code class="sourceCode default">T~</code> syntax<a href="#t-syntax" class="self-link"></a></h2>
<p>The approach we propose in this paper is that a function parameter
whose declared type is <code class="sourceCode default">T~</code>, where
<code class="sourceCode default">T</code> is the name of a template
parameter of the function, is a forwarding reference. The main advantage
of this syntax is its consistency with the reference collapsing rules in
the same way as the current forwarding reference syntax,
<code class="sourceCode default">T&amp;&amp;</code>. Like
<code class="sourceCode default">T&amp;&amp;</code>, the syntax
<code class="sourceCode default">T~</code> requires only the addition of
a special template argument deduction rule to ensure that
<code class="sourceCode default">T</code> is deduced as a type that will
give the appropriate reference type after the collapsing rules are
applied to <code class="sourceCode default">T~</code>.</p>
<p>The <code class="sourceCode default">T~</code> syntax has two
disadvantages. The first is that all function templates that currently
perform perfect forwarding using
<code class="sourceCode default">T&amp;&amp;</code>, including Standard
Library function templates, would need to be updated to accept
<code class="sourceCode default">T~</code>; otherwise, they would
forward rlvalues as xvalues, not as rlvalues. The second is that when a
programmer wants to write a function template that accepts rlvalues,
<em>not</em> glvalues, of any type and deduces that type, a constraint
must be introduced into the declaration, as we have done in our proposed
declaration of <code class="sourceCode default">std::disengage</code>.
This annoyance very rarely arises in the context of
<code class="sourceCode default">T&amp;&amp;</code> forwarding
references, because few situations arise where a function template must
accept <em>only</em> rvalues but doesn’t care about the types of those
rvalues. We anticipate that this annoyance will occur much more
frequently if the <code class="sourceCode default">T~</code> syntax for
forwarding references is adopted.</p>
<h2 data-number="9.2" id="t-syntax-1"><span class="header-section-number">9.2</span>
<code class="sourceCode default">T&amp;&amp;</code> syntax<a href="#t-syntax-1" class="self-link"></a></h2>
<p>To enable all function templates that currently accept forwarding
references to perfectly forward rlvalues without any changes to their
signatures, EWG could adopt an approach in which
<code class="sourceCode default">T&amp;&amp;</code> gains the ability to
perfectly forward rlvalues. However, all such approaches known to the
authors have considerable disadvantages. Furthermore, adopting such an
approach will not enable such function templates to
<em>automatically</em> begin supporting rlvalue forwarding; while the
signatures of such functions would not need to change, the function
implementations could not effect rlvalue forwarding using the syntax
<code class="sourceCode default">std::forward&lt;T&gt;(t)</code>, since
such a function call would never be able to disengage
<code class="sourceCode default">t</code> and transfer ownership to the
result of the function call.</p>
<h3 data-number="9.2.1" id="subapproach-1-changing-the-reference-collapsing-rules"><span class="header-section-number">9.2.1</span> Subapproach 1: Changing the
reference collapsing rules<a href="#subapproach-1-changing-the-reference-collapsing-rules" class="self-link"></a></h3>
<p>One possible approach that would allow the
<code class="sourceCode default">T&amp;&amp;</code> syntax to perfectly
forward rlvalues is to specify that
<code class="sourceCode default">T~&amp;&amp;</code> collapses to
<code class="sourceCode default">T~</code>, not
<code class="sourceCode default">T&amp;&amp;</code>. Unfortunately, this
violates the principle of lesser privilege discussed in the Summary of
Part I. We do not fully understand the practical implications of such a
counterintuitive reference collapsing rule. Standardizing this rule
might not be catastrophic for the safety of the language, because a
variable whose type is spelled
<code class="sourceCode default">T&amp;&amp;</code> and turns out to be
an owning reference is unlikely to be destroyed unintentionally; the
<code class="sourceCode default">reloc</code> operator must be used to
transfer ownership to another owning reference. However, having
<code class="sourceCode default">T~&amp;&amp;</code> collapse to
<code class="sourceCode default">T~</code> would interfere with the
declarations of the <code class="sourceCode default">std::get</code>
function templates for
<code class="sourceCode default">std::tuple</code>. When
<code class="sourceCode default">std::get&lt;T~&gt;</code> is called on
an rvalue of type <code class="sourceCode default">std::tuple</code>,
one of whose element types is
<code class="sourceCode default">T~</code>, the declared return type is
<code class="sourceCode default">U&amp;&amp;</code>, where
<code class="sourceCode default">U</code> is
<code class="sourceCode default">T~</code>. If
<code class="sourceCode default">T~&amp;&amp;</code> is
<code class="sourceCode default">T~</code>, then the result of the call
is an rlvalue, which it should not be, since the only way to return an
rlvalue would be to leave the tuple in a partially relocated state. This
issue with <code class="sourceCode default">std::get</code> was not
immediately obvious to the authors, and other unanticipated issues are
likely if this reference collapsing rule is adopted.</p>
<h3 data-number="9.2.2" id="subapproach-2-changing-the-reference-collapsing-rules-but-only-for-forwarding-references"><span class="header-section-number">9.2.2</span> Subapproach 2: Changing the
reference collapsing rules but only for forwarding references<a href="#subapproach-2-changing-the-reference-collapsing-rules-but-only-for-forwarding-references" class="self-link"></a></h3>
<p>A variant of subapproach 1 is to retain the natural reference
collapsing rules in which
<code class="sourceCode default">T~&amp;&amp;</code> collapses to
<code class="sourceCode default">T&amp;&amp;</code> but add a special
exemption solely for forwarding references: When
<code class="sourceCode default">U&amp;&amp;</code> is a forwarding
reference and <code class="sourceCode default">U</code> is
<code class="sourceCode default">T~</code>, the result is
<code class="sourceCode default">T~</code>, while in all other contexts,
the result would be <code class="sourceCode default">T&amp;&amp;</code>.
That the meaning of code would depend too much on whether a reference is
a forwarding reference is the main disadvantage of this approach.</p>
<h3 data-number="9.2.3" id="subapproach-3-making-reference-collapsing-ill-formed-outside-forwarding-references"><span class="header-section-number">9.2.3</span> Subapproach 3: Making
reference collapsing ill formed outside forwarding references<a href="#subapproach-3-making-reference-collapsing-ill-formed-outside-forwarding-references" class="self-link"></a></h3>
<p>A variant of subapproach 2 is to make
<code class="sourceCode default">T~&amp;&amp;</code> collapse to
<code class="sourceCode default">T~</code> in forwarding reference
context and be ill formed in every other context. Such an approach
avoids the main disadvantage of the subapproach 1 but suffers from the
same issue as subapproach 1 concerning
<code class="sourceCode default">std::get</code> and forces writers of
generic code to guard against the creation of the
<code class="sourceCode default">T~&amp;&amp;</code> type.</p>
<h3 data-number="9.2.4" id="subapproach-4-abominable-types"><span class="header-section-number">9.2.4</span> Subapproach 4: Abominable
types<a href="#subapproach-4-abominable-types" class="self-link"></a></h3>
<p>Another subapproach for avoiding counterintuitive reference
collapsing outside of forwarding references is to specify that
<code class="sourceCode default">T~&amp;&amp;</code> is neither
<code class="sourceCode default">T~</code> nor
<code class="sourceCode default">T&amp;&amp;</code> but is adjusted to
<code class="sourceCode default">T~</code> in a function declaration
that uses a forwarding reference. In all other contexts,
<code class="sourceCode default">T~&amp;&amp;</code> would be an
<em>abominable type</em>, and attempting to declare a variable or
evaluate an expression whose type would be
<code class="sourceCode default">T~&amp;&amp;</code> would be ill
formed. This subapproach suffers from the same issue with
<code class="sourceCode default">std::get</code> as subapproaches 1 and
3 but might avoid the disadvantages of subapproach 3 in other contexts.
Unfortunately, if WG21 adopts this subapproach and it later turns out to
be untenable, removing the abominable types from the language and
specify a different behavior will be difficult.</p>
<h2 data-number="9.3" id="a-completely-different-syntax"><span class="header-section-number">9.3</span> A completely different syntax<a href="#a-completely-different-syntax" class="self-link"></a></h2>
<p>We could invent a new syntax for forwarding references that would
perfectly forward rlvalues, such as
<code class="sourceCode default">T&amp;&amp;&amp;</code> or
<code class="sourceCode default">T~~</code>. This approach would avoid
all the disadvantages associated with the
<code class="sourceCode default">T&amp;&amp;</code> syntax and the
second disadvantage associated with the
<code class="sourceCode default">T~</code> syntax but suffers from a
severe disadvantage of its own: It removes design space for more general
improvements to perfect forwarding, such as a syntax that would enable
forwarding of overload sets or <em>braced-init-lists</em>.</p>
<h2 data-number="9.4" id="conclusion-on-forwarding-reference-syntax"><span class="header-section-number">9.4</span> Conclusion on forwarding
reference syntax<a href="#conclusion-on-forwarding-reference-syntax" class="self-link"></a></h2>
<p>We propose the <code class="sourceCode default">T~</code> syntax
because, although it is imperfect, its problems are less severe than
those introduced by all known alternatives. The problems with the
<code class="sourceCode default">T~</code> syntax parallel the problems
with the existing <code class="sourceCode default">T&amp;&amp;</code>
syntax in current C++, which have proven to be tractable.</p>
<h1 data-number="10" id="appendix-c-alternative-names"><span class="header-section-number">10</span> Appendix C: Alternative names<a href="#appendix-c-alternative-names" class="self-link"></a></h1>
<p>A possible alternative name for <em>rlvalue</em> is <em>dvalue</em>,
the <em>d</em> of which connotes permission to <em>destroy</em> the
referent. The name <em>dvalue</em> is analogous to <em>xvalue</em>,
whereas using the term <em>rlvalue</em> is more comparable to referring
to xvalues as <em>mvalues</em>, i.e., connoting the likely (but not
certain) fate of the object rather than the permission granted to the
holder of the reference.</p>
<h1 data-number="11" id="bibliography"><span class="header-section-number">11</span> References<a href="#bibliography" class="self-link"></a></h1>
<div id="refs" class="references csl-bib-body hanging-indent" role="doc-bibliography">
<div id="ref-D2785" class="csl-entry" role="doc-biblioentry">
[D2785] Sébastien Bini, Ed Catmur. 2023-01-30. Relocating prvalues. <a href="https://github.com/SebastienBini/cpp-relocation-proposal/blob/main/relocation.bs"><div class="csl-block">https://github.com/SebastienBini/cpp-relocation-proposal/blob/main/relocation.bs</div></a>
</div>
<div id="ref-N4158" class="csl-entry" role="doc-biblioentry">
[N4158] Pablo Halpern. 2014-10-12. Destructive Move (Rev 1). <a href="https://wg21.link/n4158"><div class="csl-block">https://wg21.link/n4158</div></a>
</div>
<div id="ref-P0023R0" class="csl-entry" role="doc-biblioentry">
[P0023R0] Denis Bider. 2016-04-08. Relocator: Efficiently moving
objects. <a href="https://wg21.link/p0023r0"><div class="csl-block">https://wg21.link/p0023r0</div></a>
</div>
<div id="ref-P0644R1" class="csl-entry" role="doc-biblioentry">
[P0644R1] Barry Revzin. 2017-10-08. Forward without forward. <a href="https://wg21.link/p0644r1"><div class="csl-block">https://wg21.link/p0644r1</div></a>
</div>
<div id="ref-P1029R1" class="csl-entry" role="doc-biblioentry">
[P1029R1] Niall Douglas. 2018-08-07. [[move_relocates]]. <a href="https://wg21.link/p1029r1"><div class="csl-block">https://wg21.link/p1029r1</div></a>
</div>
<div id="ref-P1029R3" class="csl-entry" role="doc-biblioentry">
[P1029R3] Niall Douglas. 2020-01-12. move = bitcopies. <a href="https://wg21.link/p1029r3"><div class="csl-block">https://wg21.link/p1029r3</div></a>
</div>
<div id="ref-P1144R6" class="csl-entry" role="doc-biblioentry">
[P1144R6] Arthur O’Dwyer. 2022-06-10. Object relocation in terms of move
plus destroy. <a href="https://wg21.link/p1144r6"><div class="csl-block">https://wg21.link/p1144r6</div></a>
</div>
<div id="ref-P1144R7" class="csl-entry" role="doc-biblioentry">
[P1144R7] Arthur O’Dwyer. 2023-03-10. std::is_trivially_relocatable. <a href="https://wg21.link/p1144r7"><div class="csl-block">https://wg21.link/p1144r7</div></a>
</div>
<div id="ref-P2786R0" class="csl-entry" role="doc-biblioentry">
[P2786R0] Mungo Gill, Alisdair Meredith. 2023-02-11. Trivial
relocatability options. <a href="https://wg21.link/p2786r0"><div class="csl-block">https://wg21.link/p2786r0</div></a>
</div>
</div>
</div>
</div>
</body>
</html>
