<!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="2022-10-17" />
  <title>`common_reference_t` of `reference_wrapper` Should Be a 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.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
      ul.task-list{list-style: none;}
      pre > code.sourceCode { white-space: pre; position: relative; }
      pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
      pre > code.sourceCode > span:empty { height: 1.2em; }
      code.sourceCode > span { color: inherit; text-decoration: inherit; }
      div.sourceCode { margin: 1em 0; }
      pre.sourceCode { margin: 0; }
      @media screen {
      div.sourceCode { overflow: auto; }
      }
      @media print {
      pre > code.sourceCode { white-space: pre-wrap; }
      pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
      }
      pre.numberSource code
        { counter-reset: source-line 0; }
      pre.numberSource code > span
        { position: relative; left: -4em; counter-increment: source-line; }
      pre.numberSource code > span > a:first-child::before
        { content: counter(source-line);
          position: relative; left: -1em; text-align: right; vertical-align: baseline;
          border: none; display: inline-block;
          -webkit-touch-callout: none; -webkit-user-select: none;
          -khtml-user-select: none; -moz-user-select: none;
          -ms-user-select: none; user-select: none;
          padding: 0 4px; width: 4em;
          color: #aaaaaa;
        }
      pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa;  padding-left: 4px; }
      div.sourceCode
        {  background-color: #f6f8fa; }
      @media screen {
      pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
      }
      code span. { } /* Normal */
      code span.al { color: #ff0000; } /* Alert */
      code span.an { } /* Annotation */
      code span.at { } /* Attribute */
      code span.bn { color: #9f6807; } /* BaseN */
      code span.bu { color: #9f6807; } /* BuiltIn */
      code span.cf { color: #00607c; } /* ControlFlow */
      code span.ch { color: #9f6807; } /* Char */
      code span.cn { } /* Constant */
      code span.co { color: #008000; font-style: italic; } /* Comment */
      code span.cv { color: #008000; font-style: italic; } /* CommentVar */
      code span.do { color: #008000; } /* Documentation */
      code span.dt { color: #00607c; } /* DataType */
      code span.dv { color: #9f6807; } /* DecVal */
      code span.er { color: #ff0000; font-weight: bold; } /* Error */
      code span.ex { } /* Extension */
      code span.fl { color: #9f6807; } /* Float */
      code span.fu { } /* Function */
      code span.im { } /* Import */
      code span.in { color: #008000; } /* Information */
      code span.kw { color: #00607c; } /* Keyword */
      code span.op { color: #af1915; } /* Operator */
      code span.ot { } /* Other */
      code span.pp { color: #6f4e37; } /* Preprocessor */
      code span.re { } /* RegionMarker */
      code span.sc { color: #9f6807; } /* SpecialChar */
      code span.ss { color: #9f6807; } /* SpecialString */
      code span.st { color: #9f6807; } /* String */
      code span.va { } /* Variable */
      code span.vs { color: #9f6807; } /* VerbatimString */
      code span.wa { color: #008000; font-weight: bold; } /* Warning */
      code.diff {color: #898887}
      code.diff span.va {color: #006e28}
      code.diff span.st {color: #bf0303}
  </style>
  <style type="text/css">
body {
margin: 5em;
font-family: serif;

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

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

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

code.sourceCode > span { display: inline; }
</style>
  <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"><code class="sourceCode default">common_reference_t</code> of <code class="sourceCode default">reference_wrapper</code> Should Be a Reference Type</h1>

<table style="border:none;float:right">
  <tr>
    <td>Document #:</td>
    <td>P2655R1</td>
  </tr>
  <tr>
    <td>Date:</td>
    <td>2022-10-17</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>
      SG9, LEWG<br>
    </td>
  </tr>
  <tr>
    <td style="vertical-align:top">Reply-to:</td>
    <td>
      Hui Xie<br>&lt;<a href="mailto:hui.xie1990@gmail.com" class="email">hui.xie1990@gmail.com</a>&gt;<br>
      S. Levent Yilmaz<br>&lt;<a href="mailto:levent.yilmaz@gmail.com" class="email">levent.yilmaz@gmail.com</a>&gt;<br>
    </td>
  </tr>
</table>

</header>
<div style="clear:both">
<div id="TOC" role="doc-toc">
<h1 id="toctitle">Contents</h1>
<ul>
<li><a href="#revision-history"><span class="toc-section-number">1</span> Revision History<span></span></a>
<ul>
<li><a href="#r1"><span class="toc-section-number">1.1</span> R1<span></span></a></li>
<li><a href="#r0"><span class="toc-section-number">1.2</span> R0<span></span></a></li>
</ul></li>
<li><a href="#abstract"><span class="toc-section-number">2</span> Abstract<span></span></a></li>
<li><a href="#motivation-and-examples"><span class="toc-section-number">3</span> Motivation and Examples<span></span></a></li>
<li><a href="#design"><span class="toc-section-number">4</span> Design<span></span></a>
<ul>
<li><a href="#why-should-the-result-be-t-and-not-reference_wrappert"><span class="toc-section-number">4.1</span> Why Should the Result be <code class="sourceCode default">T&amp;</code> and not <code class="sourceCode default">reference_wrapper&lt;T&gt;</code><span></span></a></li>
<li><a href="#alternatives-considered"><span class="toc-section-number">4.2</span> Alternatives Considered<span></span></a>
<ul>
<li><a href="#option-1-support-exact-same-type-with-cv-ref-variations"><span class="toc-section-number">4.2.1</span> Option 1: Support Exact Same Type with CV-Ref Variations<span></span></a></li>
<li><a href="#option-2-treat-reference_wrappert-as-t"><span class="toc-section-number">4.2.2</span> Option 2: Treat <code class="sourceCode default">reference_wrapper&lt;T&gt;</code> as <code class="sourceCode default">T&amp;</code><span></span></a></li>
</ul></li>
<li><a href="#supporting-all-compatible-conversions-option-3"><span class="toc-section-number">4.3</span> Supporting All Compatible Conversions (Option 3)<span></span></a></li>
</ul></li>
<li><a href="#implementation-experience"><span class="toc-section-number">5</span> Implementation Experience<span></span></a></li>
<li><a href="#wording"><span class="toc-section-number">6</span> Wording<span></span></a>
<ul>
<li><a href="#feature-test-macro"><span class="toc-section-number">6.1</span> Feature Test Macro<span></span></a></li>
</ul></li>
<li><a href="#bibliography"><span class="toc-section-number">7</span> References<span></span></a></li>
</ul>
</div>
<h1 data-number="1" id="revision-history"><span class="header-section-number">1</span> Revision History<a href="#revision-history" class="self-link"></a></h1>
<h2 data-number="1.1" id="r1"><span class="header-section-number">1.1</span> R1<a href="#r1" class="self-link"></a></h2>
<ul>
<li>Added reasons why the result should be <code class="sourceCode default">T&amp;</code></li>
<li>Support <code class="sourceCode default">const</code> and <code class="sourceCode default">volatile</code></li>
<li>Support derive-base conversions</li>
</ul>
<h2 data-number="1.2" id="r0"><span class="header-section-number">1.2</span> R0<a href="#r0" class="self-link"></a></h2>
<ul>
<li>Initial revision.</li>
</ul>
<h1 data-number="2" id="abstract"><span class="header-section-number">2</span> Abstract<a href="#abstract" class="self-link"></a></h1>
<p>This paper proposes a fix that makes the <code class="sourceCode default">common_reference_t&lt;T&amp;, reference_wrapper&lt;T&gt;&gt;</code> a reference type <code class="sourceCode default">T&amp;</code>.</p>
<h1 data-number="3" id="motivation-and-examples"><span class="header-section-number">3</span> Motivation and Examples<a href="#motivation-and-examples" class="self-link"></a></h1>
<p>C++20 introduced the meta-programming utility <code class="sourceCode default">common_reference</code> <span>21.3.8.7
 <a href="https://wg21.link/meta.trans.other">[meta.trans.other]</a></span> in order to programmatically determine a common reference type to which one or more types can be converted or bounded.</p>
<p>The precise rules are rather convoluted, but roughly speaking, for given two non-reference types <code class="sourceCode default">X</code> and <code class="sourceCode default">Y</code>, <code class="sourceCode default">common_reference&lt;X&amp;, Y&amp;&gt;</code> is equivalent to the expression <code class="sourceCode default">decltype(false ? declval&lt;X&amp;&gt;() : declval&lt;Y&amp;&gt;())</code> provided it is valid. And if not, then user or a library is free to specialize the <code class="sourceCode default">basic_common_reference</code> trait for any given type(s). (Two such specializations are provided by the standard library, namely, for <code class="sourceCode default">std::pair</code> and <code class="sourceCode default">std::tuple</code> which map <code class="sourceCode default">common_reference</code> to their respective elements.) And if no such specialization exists, then the result is <code class="sourceCode default">common_type&lt;X,Y&gt;</code>.</p>
<p>The canonical use of <code class="sourceCode default">reference_wrapper&lt;T&gt;</code> is its being a surrogate for <code class="sourceCode default">T&amp;</code>. So it might be surprising to find out the following:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb1-1"><a href="#cb1-1"></a><span class="dt">int</span> i <span class="op">=</span> <span class="dv">1</span>, j <span class="op">=</span> <span class="dv">2</span>;</span>
<span id="cb1-2"><a href="#cb1-2"></a>std<span class="op">::</span>reference_wrapper<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;</span> jr <span class="op">=</span> j; <span class="co">// ok - implicit constructor</span></span>
<span id="cb1-3"><a href="#cb1-3"></a><span class="dt">int</span> <span class="op">&amp;</span> ir <span class="op">=</span> std<span class="op">::</span>ref<span class="op">(</span>i<span class="op">)</span>; <span class="co">// ok - implicit conversion</span></span>
<span id="cb1-4"><a href="#cb1-4"></a><span class="dt">int</span> <span class="op">&amp;</span> r <span class="op">=</span> <span class="kw">false</span> <span class="op">?</span> i <span class="op">:</span> std<span class="op">::</span>ref<span class="op">(</span>j<span class="op">)</span>; <span class="co">// error - conditional expression is ambiguous.</span></span></code></pre></div>
<p>The reason for the error is not because <code class="sourceCode default">i</code> and <code class="sourceCode default">ref(j)</code>, an <code class="sourceCode default">int&amp;</code> and a <code class="sourceCode default">reference_wrapper&lt;int&gt;</code>, are incompatible. It is because they are too compatible! Both types can be converted to one another, so the type of the ternary expression is ambiguous.</p>
<p>Hence, per the current rules of <code class="sourceCode default">common_reference</code>, given lack of a specialization, the evaluation falls back to <code class="sourceCode default">common_type&lt;T, reference_wrapper&lt;T&gt;&gt;</code>, whose <code class="sourceCode default">::type</code> is valid and equal to <code class="sourceCode default">T</code>. In other words, the <code class="sourceCode default">common_reference</code> type trait utility determines that the reference type to which both <code class="sourceCode default">T&amp;</code> and a <code class="sourceCode default">reference_wrapper&lt;T&gt;</code> can bind is a prvalue <code class="sourceCode default">T</code>!</p>
<p>The authors believe this current determination logic for <code class="sourceCode default">common_reference</code> for an lvalue reference to a type <code class="sourceCode default">T</code> and its <code class="sourceCode default">reference_wrapper&lt;T&gt;</code> is merely an accident, and is incompatible with the canonical purpose of the <code class="sourceCode default">reference_wrapper</code>. The answer should have been <code class="sourceCode default">T&amp;</code>. (There is no ambiguity with the <code class="sourceCode default">common_reference</code> of a prvalue T and reference_wrapper<T>, since former is convertible to latter, but not vice versa).</p>
<p>This article proposes an update to the standard which would change the behavior of <code class="sourceCode default">common_reference</code> to evaluate as <code class="sourceCode default">T&amp;</code> given <code class="sourceCode default">T&amp;</code> and an a <code class="sourceCode default">reference_wrapper&lt;T&gt;</code>, commutatively. Any evolution to implicit conversion semantics of <code class="sourceCode default">reference_wrapper</code>, or of the ternary operator for that matter, is out of the question. Therefore, the authors propose to implement this change via providing a partial specialization of <code class="sourceCode default">basic_common_reference</code> trait.</p>
<p>Below are some motivating examples:</p>
<table>
<thead>
<tr class="header">
<th><div style="text-align:center">
<strong>C++20</strong>
</div></th>
<th><div style="text-align:center">
<strong>Proposed</strong>
</div></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><div class="sourceCode" id="cb2"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb2-1"><a href="#cb2-1"></a><span class="kw">static_assert</span><span class="op">(</span>same_as<span class="op">&lt;</span></span>
<span id="cb2-2"><a href="#cb2-2"></a>                common_reference_t<span class="op">&lt;</span><span class="dt">int</span><span class="op">&amp;</span>, reference_wrapper<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;&gt;</span>,</span>
<span id="cb2-3"><a href="#cb2-3"></a>                <span class="dt">int</span><span class="op">&gt;)</span>;</span>
<span id="cb2-4"><a href="#cb2-4"></a></span>
<span id="cb2-5"><a href="#cb2-5"></a><span class="kw">static_assert</span><span class="op">(</span>same_as<span class="op">&lt;</span></span>
<span id="cb2-6"><a href="#cb2-6"></a>                common_reference_t<span class="op">&lt;</span><span class="dt">int</span><span class="op">&amp;</span>, reference_wrapper<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;&amp;&gt;</span>,</span>
<span id="cb2-7"><a href="#cb2-7"></a>                <span class="dt">int</span><span class="op">&gt;)</span>;</span></code></pre></div></td>
<td><div class="sourceCode" id="cb3"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb3-1"><a href="#cb3-1"></a><span class="kw">static_assert</span><span class="op">(</span>same_as<span class="op">&lt;</span></span>
<span id="cb3-2"><a href="#cb3-2"></a>                common_reference_t<span class="op">&lt;</span><span class="dt">int</span><span class="op">&amp;</span>, reference_wrapper<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;&gt;</span>,</span>
<span id="cb3-3"><a href="#cb3-3"></a>                <span class="dt">int</span><span class="op">&amp;&gt;)</span>;</span>
<span id="cb3-4"><a href="#cb3-4"></a></span>
<span id="cb3-5"><a href="#cb3-5"></a><span class="kw">static_assert</span><span class="op">(</span>same_as<span class="op">&lt;</span></span>
<span id="cb3-6"><a href="#cb3-6"></a>                common_reference_t<span class="op">&lt;</span><span class="dt">int</span><span class="op">&amp;</span>, reference_wrapper<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;&amp;&gt;</span>,</span>
<span id="cb3-7"><a href="#cb3-7"></a>                <span class="dt">int</span><span class="op">&amp;&gt;)</span>;</span></code></pre></div></td>
</tr>
<tr class="even">
<td><div class="sourceCode" id="cb4"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb4-1"><a href="#cb4-1"></a><span class="kw">class</span> MyClass <span class="op">{</span></span>
<span id="cb4-2"><a href="#cb4-2"></a>    vector<span class="op">&lt;</span>vector<span class="op">&lt;</span>Foo<span class="op">&gt;&gt;</span> foos_;</span>
<span id="cb4-3"><a href="#cb4-3"></a>    Foo delimiter_;</span>
<span id="cb4-4"><a href="#cb4-4"></a></span>
<span id="cb4-5"><a href="#cb4-5"></a>   <span class="kw">public</span><span class="op">:</span></span>
<span id="cb4-6"><a href="#cb4-6"></a>    <span class="dt">void</span> f<span class="op">()</span> <span class="op">{</span></span>
<span id="cb4-7"><a href="#cb4-7"></a>        <span class="kw">auto</span> r <span class="op">=</span> views<span class="op">::</span>join_with<span class="op">(</span>foos_, </span>
<span id="cb4-8"><a href="#cb4-8"></a>                   views<span class="op">::</span>single<span class="op">(</span>std<span class="op">::</span>ref<span class="op">(</span>delimiter_<span class="op">)))</span>;</span>
<span id="cb4-9"><a href="#cb4-9"></a>        <span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span><span class="op">&amp;&amp;</span> foo <span class="op">:</span> r<span class="op">)</span> <span class="op">{</span></span>
<span id="cb4-10"><a href="#cb4-10"></a>          <span class="co">// foo is a temporary copy</span></span>
<span id="cb4-11"><a href="#cb4-11"></a>        <span class="op">}</span></span>
<span id="cb4-12"><a href="#cb4-12"></a>    <span class="op">}</span></span>
<span id="cb4-13"><a href="#cb4-13"></a><span class="op">}</span>;</span></code></pre></div></td>
<td><div class="sourceCode" id="cb5"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb5-1"><a href="#cb5-1"></a><span class="kw">class</span> MyClass <span class="op">{</span></span>
<span id="cb5-2"><a href="#cb5-2"></a>    vector<span class="op">&lt;</span>vector<span class="op">&lt;</span>Foo<span class="op">&gt;&gt;</span> foos_;</span>
<span id="cb5-3"><a href="#cb5-3"></a>    Foo delimiter_;</span>
<span id="cb5-4"><a href="#cb5-4"></a></span>
<span id="cb5-5"><a href="#cb5-5"></a>   <span class="kw">public</span><span class="op">:</span></span>
<span id="cb5-6"><a href="#cb5-6"></a>    <span class="dt">void</span> f<span class="op">()</span> <span class="op">{</span></span>
<span id="cb5-7"><a href="#cb5-7"></a>        <span class="kw">auto</span> r <span class="op">=</span> views<span class="op">::</span>join_with<span class="op">(</span>foos_, </span>
<span id="cb5-8"><a href="#cb5-8"></a>                   views<span class="op">::</span>single<span class="op">(</span>std<span class="op">::</span>ref<span class="op">(</span>delimiter_<span class="op">)))</span>;</span>
<span id="cb5-9"><a href="#cb5-9"></a>        <span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span><span class="op">&amp;&amp;</span> foo <span class="op">:</span> r<span class="op">)</span> <span class="op">{</span></span>
<span id="cb5-10"><a href="#cb5-10"></a>          <span class="co">// foo is a reference to the original element</span></span>
<span id="cb5-11"><a href="#cb5-11"></a>        <span class="op">}</span></span>
<span id="cb5-12"><a href="#cb5-12"></a>    <span class="op">}</span></span>
<span id="cb5-13"><a href="#cb5-13"></a><span class="op">}</span>;</span></code></pre></div></td>
</tr>
<tr class="odd">
<td><div class="sourceCode" id="cb6"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb6-1"><a href="#cb6-1"></a><span class="kw">class</span> MyClass <span class="op">{</span></span>
<span id="cb6-2"><a href="#cb6-2"></a>    vector<span class="op">&lt;</span>Foo<span class="op">&gt;</span> foo1s_;</span>
<span id="cb6-3"><a href="#cb6-3"></a>    Foo foo2_;</span>
<span id="cb6-4"><a href="#cb6-4"></a></span>
<span id="cb6-5"><a href="#cb6-5"></a>   <span class="kw">public</span><span class="op">:</span></span>
<span id="cb6-6"><a href="#cb6-6"></a>    <span class="dt">void</span> f<span class="op">()</span> <span class="op">{</span></span>
<span id="cb6-7"><a href="#cb6-7"></a>        <span class="kw">auto</span> r <span class="op">=</span> views<span class="op">::</span>concat<span class="op">(</span>foo1s_, </span>
<span id="cb6-8"><a href="#cb6-8"></a>                   views<span class="op">::</span>single<span class="op">(</span>std<span class="op">::</span>ref<span class="op">(</span>foo2_<span class="op">)))</span>;</span>
<span id="cb6-9"><a href="#cb6-9"></a>        <span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span><span class="op">&amp;&amp;</span> foo <span class="op">:</span> r<span class="op">)</span> <span class="op">{</span></span>
<span id="cb6-10"><a href="#cb6-10"></a>          <span class="co">// foo is a temporary copy</span></span>
<span id="cb6-11"><a href="#cb6-11"></a>        <span class="op">}</span></span>
<span id="cb6-12"><a href="#cb6-12"></a>    <span class="op">}</span></span>
<span id="cb6-13"><a href="#cb6-13"></a><span class="op">}</span>;</span></code></pre></div></td>
<td><div class="sourceCode" id="cb7"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb7-1"><a href="#cb7-1"></a><span class="kw">class</span> MyClass <span class="op">{</span></span>
<span id="cb7-2"><a href="#cb7-2"></a>    vector<span class="op">&lt;</span>Foo<span class="op">&gt;</span> foo1s_;</span>
<span id="cb7-3"><a href="#cb7-3"></a>    Foo foo2_;</span>
<span id="cb7-4"><a href="#cb7-4"></a></span>
<span id="cb7-5"><a href="#cb7-5"></a>   <span class="kw">public</span><span class="op">:</span></span>
<span id="cb7-6"><a href="#cb7-6"></a>    <span class="dt">void</span> f<span class="op">()</span> <span class="op">{</span></span>
<span id="cb7-7"><a href="#cb7-7"></a>        <span class="kw">auto</span> r <span class="op">=</span> views<span class="op">::</span>concat<span class="op">(</span>foo1s_, </span>
<span id="cb7-8"><a href="#cb7-8"></a>                   views<span class="op">::</span>single<span class="op">(</span>std<span class="op">::</span>ref<span class="op">(</span>foo2_<span class="op">)))</span>;</span>
<span id="cb7-9"><a href="#cb7-9"></a>        <span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span><span class="op">&amp;&amp;</span> foo <span class="op">:</span> r<span class="op">)</span> <span class="op">{</span></span>
<span id="cb7-10"><a href="#cb7-10"></a>          <span class="co">// foo is a reference to the original element</span></span>
<span id="cb7-11"><a href="#cb7-11"></a>        <span class="op">}</span></span>
<span id="cb7-12"><a href="#cb7-12"></a>    <span class="op">}</span></span>
<span id="cb7-13"><a href="#cb7-13"></a><span class="op">}</span>;</span></code></pre></div></td>
</tr>
</tbody>
</table>
<p>In the second and the third example, the user would like to use <code class="sourceCode default">views::join_with</code> and <code class="sourceCode default">views::concat</code> <span class="citation" data-cites="P2542R2">[<a href="#ref-P2542R2" role="doc-biblioref">P2542R2</a>]</span>, respectively, with a range of <code class="sourceCode default">Foo</code>s and a single <code class="sourceCode default">Foo</code> for which they use a <code class="sourceCode default">reference_wrapper</code> to avoid copies. Both of the range adaptors rely on <code class="sourceCode default">common_reference_t</code> in their respective implementations (and specifications). As a consequence, the counter-intuitive behavior manifests as shown, where the resultant views’ reference type is a prvalue <code class="sourceCode default">Foo</code>. There does not seem to be any way for the range adaptor implementations to account for such use cases in isolation.</p>
<h1 data-number="4" id="design"><span class="header-section-number">4</span> Design<a href="#design" class="self-link"></a></h1>
<h2 data-number="4.1" id="why-should-the-result-be-t-and-not-reference_wrappert"><span class="header-section-number">4.1</span> Why Should the Result be <code class="sourceCode default">T&amp;</code> and not <code class="sourceCode default">reference_wrapper&lt;T&gt;</code><a href="#why-should-the-result-be-t-and-not-reference_wrappert" class="self-link"></a></h2>
<p>As they can both be converted to each other, the result of <code class="sourceCode default">common_reference_t</code> can be either of them in theory. However, the authors believe that the users would expect the result to be <code class="sourceCode default">T&amp;</code>. Given the following example,</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb8-1"><a href="#cb8-1"></a><span class="kw">auto</span> r <span class="op">=</span> views<span class="op">::</span>concat<span class="op">(</span>foos, </span>
<span id="cb8-2"><a href="#cb8-2"></a>           views<span class="op">::</span>single<span class="op">(</span>std<span class="op">::</span>ref<span class="op">(</span>foo2_<span class="op">)))</span>;</span>
<span id="cb8-3"><a href="#cb8-3"></a><span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span><span class="op">&amp;&amp;</span> foo <span class="op">:</span> r<span class="op">)</span> <span class="op">{</span></span>
<span id="cb8-4"><a href="#cb8-4"></a>  foo <span class="op">=</span> anotherFoo;</span>
<span id="cb8-5"><a href="#cb8-5"></a><span class="op">}</span></span></code></pre></div>
<p>If the result is <code class="sourceCode default">reference_wrapper&lt;T&gt;</code>, the assignment inside the for loop would simply rebind the <code class="sourceCode default">reference_wrapper</code> to a different instance. On the other hand, if the result is <code class="sourceCode default">T&amp;</code>, the assignment would call the copy assignment operator of the original <code class="sourceCode default">foo</code>s. The authors believe that the latter design is the intent of code and is the natural choice.</p>
<h2 data-number="4.2" id="alternatives-considered"><span class="header-section-number">4.2</span> Alternatives Considered<a href="#alternatives-considered" class="self-link"></a></h2>
<p>The following are some of the alternatives that considered originally. But later dropped in favor of the one discussed in the next section.</p>
<h3 data-number="4.2.1" id="option-1-support-exact-same-type-with-cv-ref-variations"><span class="header-section-number">4.2.1</span> Option 1: Support Exact Same Type with CV-Ref Variations<a href="#option-1-support-exact-same-type-with-cv-ref-variations" class="self-link"></a></h3>
<p>One option would be to provide customisations for only <code class="sourceCode default">reference_wrapper&lt;T&gt;</code> and cv-ref <code class="sourceCode default">T</code>. Note that this version is rather restrictive:</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb9-1"><a href="#cb9-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> T, <span class="kw">class</span> U, <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span><span class="op">&gt;</span> <span class="kw">class</span> TQual,</span>
<span id="cb9-2"><a href="#cb9-2"></a>          <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span><span class="op">&gt;</span> <span class="kw">class</span> UQual<span class="op">&gt;</span></span>
<span id="cb9-3"><a href="#cb9-3"></a>    <span class="kw">requires</span> std<span class="op">::</span>same_as<span class="op">&lt;</span>T, remove_cv_t<span class="op">&lt;</span>U<span class="op">&gt;&gt;</span></span>
<span id="cb9-4"><a href="#cb9-4"></a><span class="kw">struct</span> basic_common_reference<span class="op">&lt;</span>T, reference_wrapper<span class="op">&lt;</span>U<span class="op">&gt;</span>, TQual, UQual<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb9-5"><a href="#cb9-5"></a>    <span class="kw">using</span> type <span class="op">=</span> common_reference_t<span class="op">&lt;</span>TQual<span class="op">&lt;</span>T<span class="op">&gt;</span>, U<span class="op">&amp;&gt;</span>;</span>
<span id="cb9-6"><a href="#cb9-6"></a><span class="op">}</span>;</span>
<span id="cb9-7"><a href="#cb9-7"></a></span>
<span id="cb9-8"><a href="#cb9-8"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> T, <span class="kw">class</span> U, <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span><span class="op">&gt;</span> <span class="kw">class</span> TQual,</span>
<span id="cb9-9"><a href="#cb9-9"></a>          <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span><span class="op">&gt;</span> <span class="kw">class</span> UQual<span class="op">&gt;</span></span>
<span id="cb9-10"><a href="#cb9-10"></a>    <span class="kw">requires</span> std<span class="op">::</span>same_as<span class="op">&lt;</span>remove_cv_t<span class="op">&lt;</span>T<span class="op">&gt;</span>, U<span class="op">&gt;</span></span>
<span id="cb9-11"><a href="#cb9-11"></a><span class="kw">struct</span> basic_common_reference<span class="op">&lt;</span>reference_wrapper<span class="op">&lt;</span>T<span class="op">&gt;</span>, U, TQual, UQual<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb9-12"><a href="#cb9-12"></a>    <span class="kw">using</span> type <span class="op">=</span> common_reference_t<span class="op">&lt;</span>T<span class="op">&amp;</span>, UQual<span class="op">&lt;</span>U<span class="op">&gt;&gt;</span>;</span>
<span id="cb9-13"><a href="#cb9-13"></a><span class="op">}</span>;</span></code></pre></div>
<h3 data-number="4.2.2" id="option-2-treat-reference_wrappert-as-t"><span class="header-section-number">4.2.2</span> Option 2: Treat <code class="sourceCode default">reference_wrapper&lt;T&gt;</code> as <code class="sourceCode default">T&amp;</code><a href="#option-2-treat-reference_wrappert-as-t" class="self-link"></a></h3>
<p>This options completely treats <code class="sourceCode default">reference_wrapper&lt;T&gt;</code> as <code class="sourceCode default">T&amp;</code> and delegates <code class="sourceCode default">common_reference&lt;reference_wrapper&lt;T&gt;, U&gt;</code> to the <code class="sourceCode default">common_reference&lt;T&amp;, U&gt;</code>. Therefore, it would support any conversions (including derived-base conversion) that <code class="sourceCode default">T&amp;</code> can do.</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb10-1"><a href="#cb10-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> T, <span class="kw">class</span> U, <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span><span class="op">&gt;</span> <span class="kw">class</span> TQual, <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span><span class="op">&gt;</span> <span class="kw">class</span> UQual<span class="op">&gt;</span></span>
<span id="cb10-2"><a href="#cb10-2"></a>    <span class="kw">requires</span> <span class="kw">requires</span> <span class="op">{</span> <span class="kw">typename</span> common_reference<span class="op">&lt;</span>TQual<span class="op">&lt;</span>T<span class="op">&gt;</span>, U<span class="op">&amp;&gt;::</span>type; <span class="op">}</span></span>
<span id="cb10-3"><a href="#cb10-3"></a><span class="kw">struct</span> basic_common_reference<span class="op">&lt;</span>T, reference_wrapper<span class="op">&lt;</span>U<span class="op">&gt;</span>, TQual, UQual<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb10-4"><a href="#cb10-4"></a>    <span class="kw">using</span> type <span class="op">=</span> common_reference_t<span class="op">&lt;</span>TQual<span class="op">&lt;</span>T<span class="op">&gt;</span>, U<span class="op">&amp;&gt;</span>;</span>
<span id="cb10-5"><a href="#cb10-5"></a><span class="op">}</span>;</span>
<span id="cb10-6"><a href="#cb10-6"></a></span>
<span id="cb10-7"><a href="#cb10-7"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> T, <span class="kw">class</span> U, <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span><span class="op">&gt;</span> <span class="kw">class</span> TQual, <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span><span class="op">&gt;</span> <span class="kw">class</span> UQual<span class="op">&gt;</span></span>
<span id="cb10-8"><a href="#cb10-8"></a>    <span class="kw">requires</span> <span class="kw">requires</span> <span class="op">{</span> <span class="kw">typename</span> common_reference<span class="op">&lt;</span>T<span class="op">&amp;</span>, UQual<span class="op">&lt;</span>U<span class="op">&gt;&gt;::</span>type; <span class="op">}</span></span>
<span id="cb10-9"><a href="#cb10-9"></a><span class="kw">struct</span> basic_common_reference<span class="op">&lt;</span>reference_wrapper<span class="op">&lt;</span>T<span class="op">&gt;</span>, U, TQual, UQual<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb10-10"><a href="#cb10-10"></a>    <span class="kw">using</span> type <span class="op">=</span> common_reference_t<span class="op">&lt;</span>T<span class="op">&amp;</span>, UQual<span class="op">&lt;</span>U<span class="op">&gt;&gt;</span>;</span>
<span id="cb10-11"><a href="#cb10-11"></a><span class="op">}</span>;</span></code></pre></div>
<p>Immediately, it run into ambiguous specialisation problems for the following example</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb11-1"><a href="#cb11-1"></a>common_reference_t<span class="op">&lt;</span>reference_wrapper<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;</span>, reference_wrapper<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;&gt;</span>;</span></code></pre></div>
<p>A quick fix is to add another specialisation</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb12-1"><a href="#cb12-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> T, <span class="kw">class</span> U, <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span><span class="op">&gt;</span> <span class="kw">class</span> TQual, <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span><span class="op">&gt;</span> <span class="kw">class</span> UQual<span class="op">&gt;</span></span>
<span id="cb12-2"><a href="#cb12-2"></a>    <span class="kw">requires</span> <span class="kw">requires</span> <span class="op">{</span> <span class="kw">typename</span> common_reference<span class="op">&lt;</span>T<span class="op">&amp;</span>, U<span class="op">&amp;&gt;::</span>type; <span class="op">}</span></span>
<span id="cb12-3"><a href="#cb12-3"></a><span class="kw">struct</span> basic_common_reference<span class="op">&lt;</span>reference_wrapper<span class="op">&lt;</span>T<span class="op">&gt;</span>, reference_wrapper<span class="op">&lt;</span>U<span class="op">&gt;</span>, TQual, UQual<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb12-4"><a href="#cb12-4"></a>    <span class="kw">using</span> type <span class="op">=</span> common_reference_t<span class="op">&lt;</span>T<span class="op">&amp;</span>, U<span class="op">&amp;&gt;</span>;</span>
<span id="cb12-5"><a href="#cb12-5"></a><span class="op">}</span>;</span></code></pre></div>
<p>However, this has some recursion problems.</p>
<div class="sourceCode" id="cb13"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb13-1"><a href="#cb13-1"></a>common_reference_t<span class="op">&lt;</span>reference_wrapper<span class="op">&lt;</span>reference_wrapper<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;&gt;</span>,</span>
<span id="cb13-2"><a href="#cb13-2"></a>                   reference_wrapper<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;&amp;&gt;</span>;</span></code></pre></div>
<p>The user would expect the above expression to yield <code class="sourceCode default">reference_wrapper&lt;int&gt;&amp;&gt;</code>. However it yields <code class="sourceCode default">int&amp;</code> due to the recursion logic in the specialisation.</p>
<p>And even worse,</p>
<div class="sourceCode" id="cb14"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb14-1"><a href="#cb14-1"></a>common_reference_t<span class="op">&lt;</span>reference_wrapper<span class="op">&lt;</span>reference_wrapper<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;&gt;</span>,</span>
<span id="cb14-2"><a href="#cb14-2"></a>                   <span class="dt">int</span><span class="op">&amp;&gt;</span>;</span></code></pre></div>
<p>The above expression would also yield <code class="sourceCode default">int&amp;</code> due to the recursion logic, even though the nested <code class="sourceCode default">reference_wrapper</code> is not <code class="sourceCode default">convertible_to&lt;int&amp;&gt;</code>.</p>
<p>The rational behind this option is that <code class="sourceCode default">reference_wrapper&lt;T&gt;</code> behaves exactly the same as <code class="sourceCode default">T&amp;</code>. But does it?</p>
<p>There is conversion from <code class="sourceCode default">reference_wrapper&lt;T&gt;</code> to <code class="sourceCode default">T&amp;</code>, and if the result requires another conversion, the language does not allow <code class="sourceCode default">reference_wrapper&lt;T&gt;</code> to be converted to the result.</p>
<p>This would cover majority of the use cases. However, this does not cover the derive-base conversions, i.e. <code class="sourceCode default">common_reference_t&lt;reference_wrapper&lt;Derived&gt;, Base&amp;&gt;&gt;</code>. This is a valid use case and the authors believe that it is important to support it.</p>
<h2 data-number="4.3" id="supporting-all-compatible-conversions-option-3"><span class="header-section-number">4.3</span> Supporting All Compatible Conversions (Option 3)<a href="#supporting-all-compatible-conversions-option-3" class="self-link"></a></h2>
<p>The above exposure can be extrapolated to any <em>cv</em>-qualified or other cross-type compatible conversions. That is, if <code class="sourceCode default">common_reference_t&lt;U, V&gt;</code> exists then <code class="sourceCode default">common_reference_t&lt;reference_wrapper&lt;U&gt;, V&gt;</code> and <code class="sourceCode default">common_reference_t&lt;U, reference_wrapper&lt;V&gt;&gt;</code> should also exist and be equal to it, <em>given</em> the only additional requirement that <code class="sourceCode default">reference_wrapper&lt;U&gt;</code> or <code class="sourceCode default">reference_wrapper&lt;V&gt;</code>, respectively, can be also implicitly converted to <code class="sourceCode default">common_reference_t&lt;U,V&gt;</code>. This statement only applies when the ternary conversion logic ambiguous.</p>
<p>The authors propose to support such behavior by allowing <code class="sourceCode default">basic_common_reference</code> specialization to delegate the result to that of the <code class="sourceCode default">common_reference_t</code> of the wrapped type with the other non-wrapper argument. Furthermore, impose additional constraints on this specialization to make sure that the <code class="sourceCode default">reference_wrapper</code> is convertible to this result.</p>
<p>In order to support commutativity, we need to introduce two separate specializations, and further constrain them to be mutually exclusive in order avoid ambiguity.</p>
<p>Finally, we have to explicitly disable the edge cases with nested <code class="sourceCode default">reference_wrapper</code>s since, while <code class="sourceCode default">reference_wrapper&lt;reference_wrapper&lt;T&gt;&gt;</code> is not <code class="sourceCode default">convertible_to&lt;T&amp;&gt;</code></p>
<h1 data-number="5" id="implementation-experience"><span class="header-section-number">5</span> Implementation Experience<a href="#implementation-experience" class="self-link"></a></h1>
<ul>
<li><p>The authors implemented the proposed wording below without any issue<span class="citation" data-cites="ours">[<a href="#ref-ours" role="doc-biblioref">ours</a>]</span>.</p></li>
<li><p>The authors also applied the proposed wording in LLVM’s libc++ and all libc++ tests passed.</p></li>
</ul>
<h1 data-number="6" id="wording"><span class="header-section-number">6</span> Wording<a href="#wording" class="self-link"></a></h1>
<p>Modify <span>22.10.2
 <a href="https://wg21.link/functional.syn">[functional.syn]</a></span> to add to the end of <code class="sourceCode default">reference_wrapper</code> section:</p>
<div class="add" style="color: #006e28">

<div class="sourceCode" id="cb15"><pre class="sourceCode default cpp"><code class="sourceCode default"><span id="cb15-1"><a href="#cb15-1"></a>// <em>[refwrap.common.ref] <code class="sourceCode default">common_­reference</code> related specializations</em></span>
<span id="cb15-2"><a href="#cb15-2"></a>template &lt;class R, class T, template &lt;class&gt; class RQual, template &lt;class&gt; class TQual&gt;</span>
<span id="cb15-3"><a href="#cb15-3"></a>struct basic_common_reference&lt;R, T, RQual, TQual&gt;;</span>
<span id="cb15-4"><a href="#cb15-4"></a></span>
<span id="cb15-5"><a href="#cb15-5"></a>template &lt;class T, class R, template &lt;class&gt; class TQual, template &lt;class&gt; class RQual&gt;</span>
<span id="cb15-6"><a href="#cb15-6"></a>struct basic_common_reference&lt;T, R, TQual, RQual&gt;;</span></code></pre></div>

</div>
<p>Add the following subclause to <span>22.10.6
 <a href="https://wg21.link/refwrap">[refwrap]</a></span>:</p>
<h4 class="unnumbered" data-number id="common_reference-related-specializations-refwrap.common.ref">?.?.?.? <code class="sourceCode default">common_reference</code> related specializations [refwrap.common.ref]<a href="#common_reference-related-specializations-refwrap.common.ref" class="self-link"></a></h4>
<div class="sourceCode" id="cb16"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb16-1"><a href="#cb16-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> R, <span class="kw">class</span> T, <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span><span class="op">&gt;</span> <span class="kw">class</span> RQual, <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span><span class="op">&gt;</span> <span class="kw">class</span> TQual<span class="op">&gt;</span></span>
<span id="cb16-2"><a href="#cb16-2"></a><span class="kw">struct</span> basic_common_reference<span class="op">&lt;</span>R, T, RQual, TQual<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb16-3"><a href="#cb16-3"></a>    <span class="kw">using</span> type <span class="op">=</span> <em>see below</em>;</span>
<span id="cb16-4"><a href="#cb16-4"></a><span class="op">}</span>;</span>
<span id="cb16-5"><a href="#cb16-5"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> T, <span class="kw">class</span> R, <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span><span class="op">&gt;</span> <span class="kw">class</span> TQual, <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span><span class="op">&gt;</span> <span class="kw">class</span> RQual<span class="op">&gt;</span></span>
<span id="cb16-6"><a href="#cb16-6"></a><span class="kw">struct</span> basic_common_reference<span class="op">&lt;</span>T, R, TQual, RQual<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb16-7"><a href="#cb16-7"></a>    <span class="kw">using</span> type <span class="op">=</span> <em>see below</em>;</span>
<span id="cb16-8"><a href="#cb16-8"></a><span class="op">}</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span> The following are the <em>constraints</em>, and apply to both specializations verbatim:</p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">(1.1)</a></span> <code class="sourceCode default">R</code> is a cv-unqualified <code class="sourceCode default">reference_wrapper&lt;U&gt;</code> of some type <code class="sourceCode default">U</code>. [<em>Note</em>: <code class="sourceCode default">T</code> is any cv-unqualified type, possibly a <code class="sourceCode default">reference_wrapper</code> instance. -<em>end note</em>];</li>
<li><span class="marginalizedparent"><a class="marginalized">(1.2)</a></span> <code class="sourceCode default">common_reference_t&lt;U&amp;, TQual&lt;T&gt;&gt;</code> denotes a type. Let this type be <code class="sourceCode default">Result</code>.</li>
<li><span class="marginalizedparent"><a class="marginalized">(1.3)</a></span> <code class="sourceCode default">RQual&lt;R&gt;</code> models <code class="sourceCode default">convertible_to&lt;Result&gt;</code>.</li>
<li><span class="marginalizedparent"><a class="marginalized">(1.4)</a></span> Let the above constraints be expressed in the form <code class="sourceCode default"><em>CRW</em>(R, RQual&lt;R&gt;, TQual&lt;T&gt;&gt;)</code> which evaluates to <em>true</em> when the conditions are satisfied. Then, <code class="sourceCode default"><em>CRW</em>(T, TQual&lt;T&gt;, RQual&lt;R&gt;&gt;)</code> should evaluate to <em>false</em>. [<em>Note</em>: This final requirement provides mutual exclusion of the two specializations -<em>end note</em>];</li>
</ul>
<p>The member typedef-name <code class="sourceCode default">type</code> denotes the type <code class="sourceCode default">Result</code>.</p>
<h2 data-number="6.1" id="feature-test-macro"><span class="header-section-number">6.1</span> Feature Test Macro<a href="#feature-test-macro" class="self-link"></a></h2>
<p>Add the following macro definition to <span>17.3.2
 <a href="https://wg21.link/version.syn">[version.syn]</a></span>, header <code class="sourceCode default">&lt;version&gt;</code> synopsis, with the value selected by the editor to reflect the date of adoption of this paper:</p>
<div class="sourceCode" id="cb17"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb17-1"><a href="#cb17-1"></a><span class="pp">#define __cpp_lib_common_reference_reference_wrapper_specialized  </span><span class="dv">20</span><span class="er">XXXXL</span><span class="pp"> </span><span class="co">// also in &lt;functional&gt;</span></span></code></pre></div>
<style>
.bq{
    display: block;
    margin-block-start: 1em;
    margin-block-end: 1em;
    margin-inline-start: 40px;
    margin-inline-end: 40px;
}
</style>
<h1 data-number="7" id="bibliography"><span class="header-section-number">7</span> References<a href="#bibliography" class="self-link"></a></h1>
<div id="refs" class="references hanging-indent" role="doc-bibliography">
<div id="ref-ours">
<p>[ours] Hui Xie and S. Levent Yilmaz. A proof-of-concept implementation of common_reference_t for reference_wrapper. <br />
<a href="https://github.com/huixie90/cpp_papers/tree/main/impl/ref_wrapper">https://github.com/huixie90/cpp_papers/tree/main/impl/ref_wrapper</a></p>
</div>
<div id="ref-P2542R2">
<p>[P2542R2] Hui Xie, S. Levent Yilmaz. 2022-05-11. views::concat. <br />
<a href="https://wg21.link/p2542r2">https://wg21.link/p2542r2</a></p>
</div>
</div>
</div>
</div>
</body>
</html>
