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

hyphens: auto;
line-height: 1.35;
text-align: left;
}
@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: left; }
div.section { text-align: left; }
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">Better Lookups for
<code class="sourceCode default">map</code> and
<code class="sourceCode default">unordered_map</code></h1>
<table style="border:none;float:right">
  <tr>
    <td>Document #:</td>
    <td>P3091R1</td>
  </tr>
  <tr>
    <td>Date:</td>
    <td><!-- $TimeStamp$ -->
2024-03-22 16:01 JST<!-- $ --></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>
      LEWGI<br>
    </td>
  </tr>
  <tr>
    <td style="vertical-align:top">Reply-to:</td>
    <td>
      Pablo Halpern<br>&lt;<a href="mailto:phalpern@halpernwightsoftware.com" class="email">phalpern@halpernwightsoftware.com</a>&gt;<br>
    </td>
  </tr>
</table>
</header>
<div style="clear:both">
<div id="TOC" role="doc-toc">
<h1 id="toctitle">Contents</h1>
<ul>
<li><a href="#abstract" id="toc-abstract"><span class="toc-section-number">1</span> Abstract<span></span></a></li>
<li><a href="#change-log" id="toc-change-log"><span class="toc-section-number">2</span> Change Log<span></span></a></li>
<li><a href="#motivation" id="toc-motivation"><span class="toc-section-number">3</span> Motivation<span></span></a></li>
<li><a href="#proposed-feature" id="toc-proposed-feature"><span class="toc-section-number">4</span> Proposed Feature<span></span></a>
<ul>
<li><a href="#overview" id="toc-overview"><span class="toc-section-number">4.1</span> Overview<span></span></a></li>
<li><a href="#returning-a-different-but-compatible-reference-type" id="toc-returning-a-different-but-compatible-reference-type"><span class="toc-section-number">4.2</span> Returning a Different but
Compatible Reference Type<span></span></a></li>
<li><a href="#returning-an-rvalue" id="toc-returning-an-rvalue"><span class="toc-section-number">4.3</span> Returning an
Rvalue<span></span></a></li>
<li><a href="#returning-a-type-other-than-mapped_type" id="toc-returning-a-type-other-than-mapped_type"><span class="toc-section-number">4.4</span> Returning a Type Other Than
<code class="sourceCode default">mapped_type</code><span></span></a></li>
</ul></li>
<li><a href="#before-and-after-comparisons" id="toc-before-and-after-comparisons"><span class="toc-section-number">5</span> Before and After
Comparisons<span></span></a></li>
<li><a href="#alternatives-considered" id="toc-alternatives-considered"><span class="toc-section-number">6</span> Alternatives
Considered<span></span></a>
<ul>
<li><a href="#names" id="toc-names"><span class="toc-section-number">6.1</span> Names<span></span></a></li>
<li><a href="#build-get-value-or-return-alternative-functionality-directly-into-map" id="toc-build-get-value-or-return-alternative-functionality-directly-into-map"><span class="toc-section-number">6.2</span> Build
Get-Value-or-Return-Alternative Functionality Directly into
<code class="sourceCode default">map</code><span></span></a></li>
<li><a href="#combine-optionaltvalue_or-and-optionaltor_construct" id="toc-combine-optionaltvalue_or-and-optionaltor_construct"><span class="toc-section-number">6.3</span> Combine
<code class="sourceCode default">optional&lt;T&gt;::value_or</code> and
<code class="sourceCode default">optional&lt;T&gt;::or_construct</code><span></span></a></li>
<li><a href="#lazy-evaluation-of-or_construct-argument" id="toc-lazy-evaluation-of-or_construct-argument"><span class="toc-section-number">6.4</span> Lazy Evaluation of
<code class="sourceCode default">or_construct</code>
Argument<span></span></a></li>
<li><a href="#free-functions-instead-of-members" id="toc-free-functions-instead-of-members"><span class="toc-section-number">6.5</span> Free Functions Instead of
Members<span></span></a></li>
</ul></li>
<li><a href="#implementation-experience" id="toc-implementation-experience"><span class="toc-section-number">7</span> Implementation
Experience<span></span></a></li>
<li><a href="#wording" id="toc-wording"><span class="toc-section-number">8</span> Wording<span></span></a>
<ul>
<li><a href="#feature-test-macros" id="toc-feature-test-macros"><span class="toc-section-number">8.1</span> Feature-Test
Macros<span></span></a></li>
<li><a href="#changes-to-optional" id="toc-changes-to-optional"><span class="toc-section-number">8.2</span> Changes to
<code class="sourceCode default">optional</code><span></span></a></li>
<li><a href="#changes-to-map-and-unordered_map" id="toc-changes-to-map-and-unordered_map"><span class="toc-section-number">8.3</span> Changes to
<code class="sourceCode default">map</code> and
<code class="sourceCode default">unordered_map</code><span></span></a></li>
</ul></li>
<li><a href="#acknowledgments" id="toc-acknowledgments"><span class="toc-section-number">9</span>
Acknowledgments<span></span></a></li>
<li><a href="#bibliography" id="toc-bibliography"><span class="toc-section-number">10</span> References<span></span></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>The most convenient way to look up an element of a
<code class="sourceCode default">map</code> or
<code class="sourceCode default">unordered_map</code> is to use the
index operator, i.e.,
<code class="sourceCode default">theMap[key]</code>. This operator
cannot be used, however, when 1) the container is
<code class="sourceCode default">const</code>, 2) the mapped type is not
default constructible, 3) the default-constructed value is inappropriate
for the context, or 4) the container should not be modified. These
limitations often force the user to resort to the
<code class="sourceCode default">find</code> member function, which
returns an iterator that points to a
<code class="sourceCode default">pair</code> and typically leads to more
complex code having at least one
<code class="sourceCode default">if</code> statement and/or duplicate
lookup operations. Taking inspiration from other languages, especially
Python, this paper proposes a
<code class="sourceCode default">get</code> member function that returns
<code class="sourceCode default">optional&lt;T&amp;&gt;</code> and
leverages the observers and monadic operations of
<code class="sourceCode default">optional</code> to simplify lookups for
<code class="sourceCode default">map</code> and
<code class="sourceCode default">unordered_map</code>. In addition, a
new <code class="sourceCode default">or_construct</code> observer
function is proposed for
<code class="sourceCode default">optional</code> to expand the set of
common use-cases for <code class="sourceCode default">get</code>. Note
that this proposal is built on
<code class="sourceCode default">optional&lt;T&amp;&gt;</code>, which is
described in <span class="citation" data-cites="P2988R3">[<a href="#ref-P2988R3" role="doc-biblioref">P2988R3</a>]</span> and is not
yet in the C++ Working Draft.</p>
<h1 data-number="2" id="change-log"><span class="header-section-number">2</span> Change Log<a href="#change-log" class="self-link"></a></h1>
<p><strong>R1</strong> (post 2024-02-27 LEWGI teleconference)</p>
<ul>
<li>As a result of discussions in LEWGI on 27 Feb 2024, the return value
of <code class="sourceCode default">get</code> was changed from
<code class="sourceCode default">mapped_type</code> to
<code class="sourceCode default">optional&lt;mapped_type&amp;&gt;</code>,
and the functionality of <code class="sourceCode default">get_ref</code>
and <code class="sourceCode default">get_as</code> were delegated to
<code class="sourceCode default">optional</code>. Note that
<code class="sourceCode default">optional&lt;T&amp;&gt;</code> is not
valid in C++23 but is proposed in <span class="citation" data-cites="P2988R3">[<a href="#ref-P2988R3" role="doc-biblioref">P2988R3</a>]</span> for C++26.</li>
<li>Added a proposed
<code class="sourceCode default">or_construct</code> member to
<code class="sourceCode default">optional</code></li>
<li>Proposed an enhancement of
<code class="sourceCode default">optional&lt;T&amp;&gt;::value_or</code>
over that in <span class="citation" data-cites="P2988R3">[<a href="#ref-P2988R3" role="doc-biblioref">P2988R3</a>]</span></li>
<li>Added feature-test macros</li>
</ul>
<p><strong>R0</strong> (pre-Tokyo mailing)</p>
<ul>
<li>Initial version</li>
</ul>
<h1 data-number="3" id="motivation"><span class="header-section-number">3</span> Motivation<a href="#motivation" class="self-link"></a></h1>
<p>Just about every modern computer language has, as part of the
language or its standard library, one or more associative containers
that uniquely map a key to a value, variously called
<code class="sourceCode default">map</code>,
<code class="sourceCode default">hash_map</code>,
<code class="sourceCode default">dictionary</code>, or something
similar. In C++, we have
<code class="sourceCode default">std::map</code>,
<code class="sourceCode default">std::unordered_map</code>, and
eventually (per <span class="citation" data-cites="P0429R9">[<a href="#ref-P0429R9" role="doc-biblioref">P0429R9</a>]</span> and <span class="citation" data-cites="P2767R2">[<a href="#ref-P2767R2" role="doc-biblioref">P2767R2</a>]</span>)
<code class="sourceCode default">std::flat_map</code>. The easy-to-write
and easy-to-read expression for getting a value for an associated key is
simply <code class="sourceCode default">theMap[key]</code>; in other
words, a mapped value is retrieved (and often set) using the index
operator, which returns a reference to the value associated with the
key. Unfortunately, the index operator in the C++ associative containers
has a number of shortcomings compared to many other languages.</p>
<ul>
<li>It works only for non-<code class="sourceCode default">const</code>
containers.</li>
<li>It works only for default-constructible mapped types.</li>
<li>The default-constructed object (when available) is not always the
correct identity for a given use case.</li>
<li>It modifies the container when the key is absent.</li>
</ul>
<p>Consider a <code class="sourceCode default">std::map</code> named
<code class="sourceCode default">theMap</code> that maps an integer key
to a floating-point value, modeling a sparse array of
<code class="sourceCode default">double</code>. If we want to find the
largest of the <code class="sourceCode default">double</code> values
mapped to the integer keys in the range 1 to 100, we might be tempted to
write the following loop:</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="dt">double</span> largest <span class="op">=</span> <span class="op">-</span>std<span class="op">::</span>numeric_limits<span class="op">&lt;</span><span class="dt">double</span><span class="op">&gt;::</span>infinity<span class="op">()</span>;</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span> <span class="op">(</span><span class="dt">int</span> i <span class="op">=</span> <span class="dv">1</span>; i <span class="op">&lt;=</span> <span class="dv">100</span>; <span class="op">++</span>i<span class="op">)</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>  largest <span class="op">=</span> std<span class="op">::</span>max<span class="op">(</span>largest, theMap<span class="op">[</span>i<span class="op">])</span>;</span></code></pre></div>
<p>If <code class="sourceCode default">theMap</code> is
<code class="sourceCode default">const</code>, the loop will not
compile. If any of the keys in the range
<code class="sourceCode default">[1, 100]</code> are absent from the
map, then <code class="sourceCode default">theMap[i]</code> will return
a default-constructed <code class="sourceCode default">double</code>
having value 0.0, which might or might not be desirable, depending on
whether we want to treat missing values as truly having value 0.0 or to
ignore them (or, equivalently, to treat them as having value <span class="math inline"> − ∞</span>). Finally if, before executing this
loop, <code class="sourceCode default">theMap</code> contains only, say,
five entries, then at the end of the loop, it will contain at least 100
entries, most of whose values will be zero.</p>
<p>Some alternatives avoid all these shortcomings but are significantly
less elegant and therefore more error prone. For example, the
<code class="sourceCode default">at</code> member function looks a lot
like <code class="sourceCode default">operator[]</code> and has none of
the above shortcomings, but missing keys are handled by throwing
exceptions, making this option impractical for situations other than
when the key is almost certain to exist. Moreover, a
<code class="sourceCode default">try</code>-<code class="sourceCode default">catch</code>
block within a loop is rarely a clean way to structure code:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="dt">double</span> largest <span class="op">=</span> <span class="op">-</span>std<span class="op">::</span>numeric_limits<span class="op">&lt;</span><span class="dt">double</span><span class="op">&gt;::</span>infinity<span class="op">()</span>;</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span> <span class="op">(</span><span class="dt">int</span> i <span class="op">=</span> <span class="dv">1</span>; i <span class="op">&lt;=</span> <span class="dv">100</span>; <span class="op">++</span>i<span class="op">)</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>  <span class="cf">try</span> <span class="op">{</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>    largest <span class="op">=</span> std<span class="op">::</span>max<span class="op">(</span>largest, theMap<span class="op">.</span>at<span class="op">(</span>i<span class="op">))</span>;</span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span> <span class="cf">catch</span> <span class="op">(</span><span class="kw">const</span> std<span class="op">::</span>out_of_range<span class="op">&amp;)</span> <span class="op">{</span> <span class="op">}</span></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>The above code would work with a
<code class="sourceCode default">const</code> map, would ignore missing
elements (rather than treating them as zeros), and would not populate
the map with useless entries, but many programmers would argue that the
loop is inelegant at best. In most C++ implementations, this code would
be extremely inefficient unless key misses are rare.</p>
<p>The other obvious alternative uses the
<code class="sourceCode default">find</code> member function:</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">double</span> largest <span class="op">=</span> <span class="op">-</span>std<span class="op">::</span>numeric_limits<span class="op">&lt;</span><span class="dt">double</span><span class="op">&gt;::</span>infinity<span class="op">()</span>;</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span> <span class="op">(</span><span class="dt">int</span> i <span class="op">=</span> <span class="dv">1</span>; i <span class="op">&lt;=</span> <span class="dv">100</span>; <span class="op">++</span>i<span class="op">)</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">auto</span> iter <span class="op">=</span> theMap<span class="op">.</span>find<span class="op">(</span>i<span class="op">)</span>;</span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>  <span class="cf">if</span> <span class="op">(</span>iter <span class="op">!=</span> theMap<span class="op">.</span>end<span class="op">())</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>    largest <span class="op">=</span> std<span class="op">::</span>max<span class="op">(</span>largest, iter<span class="op">-&gt;</span>second<span class="op">)</span>;</span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>This version of the loop is only slightly more verbose than our
starting point and avoids all the issues, but using iterators, needing
to call <em>two</em> member functions
(<code class="sourceCode default">find</code> and
<code class="sourceCode default">end</code>), and having to extract the
<code class="sourceCode default">second</code> member of the element
<code class="sourceCode default">pair</code> for what should be a
<em>simple</em> operation increases the cognitive load on both the
programmer and the reader. Moreover, a generic use of
<code class="sourceCode default">find</code> can yield a subtle bug.
Consider the following function template,
<code class="sourceCode default">f</code>:</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">template</span> <span class="op">&lt;</span><span class="kw">class</span> Key, <span class="kw">class</span> Value<span class="op">&gt;</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> f<span class="op">(</span><span class="kw">const</span> Key<span class="op">&amp;</span> k, <span class="kw">const</span> std<span class="op">::</span>map<span class="op">&lt;</span>Key, Value<span class="op">&gt;&amp;</span> aMap<span class="op">)</span></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>  Value obj <span class="op">=</span> <em>some-default-obj-value-expression</em>;</span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">auto</span> iter <span class="op">=</span> aMap<span class="op">.</span>find<span class="op">(</span>k<span class="op">)</span>;</span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a>  <span class="cf">if</span> <span class="op">(</span>iter <span class="op">!=</span> aMap<span class="op">.</span>end<span class="op">())</span></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a>    obj <span class="op">=</span> iter<span class="op">-&gt;</span>second;</span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a>  <span class="co">// code that uses `obj` ...</span></span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>An instantiation of <code class="sourceCode default">f</code> will
not compile unless <code class="sourceCode default">Value</code> is copy
assignable. Worse, unless tested with a nonassignable type, the bug
could go undetected for a long time. One fix would be initialize
<code class="sourceCode default">obj</code> in a single expression:</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>Value obj <span class="op">=</span> aMap<span class="op">.</span>count<span class="op">(</span>k<span class="op">)</span> <span class="op">?</span> aMap<span class="op">.</span>at<span class="op">(</span>k<span class="op">)</span> <span class="op">:</span> <em>some-default-obj-value-expression</em>;</span></code></pre></div>
<p>While correct, this solution involves two lookup operations: one for
the <code class="sourceCode default">count</code> and one for the
<code class="sourceCode default">at</code>. A better fix requires a bit
more code:</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">auto</span> iter <span class="op">=</span> aMap<span class="op">.</span>find<span class="op">(</span>k<span class="op">)</span>;</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>Value obj <span class="op">=</span> iter <span class="op">!=</span> aMap<span class="op">.</span>end<span class="op">()</span> <span class="op">?</span> iter<span class="op">-&gt;</span>second <span class="op">:</span> <em>some-default-obj-value-expression</em>;</span></code></pre></div>
<p>Note that the last solution again involves
<code class="sourceCode default">iterator</code>,
<code class="sourceCode default">pair</code>, and a conditional
expression, which is a far cry from the simplicity of
<code class="sourceCode default">operator[]</code>.</p>
<p>Let’s contrast these less-than-ideal map lookups to dictionary
lookups in another language and consider one way to write the
largest-value computation in Python:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a>inf <span class="op">=</span> <span class="bu">float</span>(<span class="st">&quot;inf&quot;</span>)</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>largest <span class="op">=</span> <span class="op">-</span>inf</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span> i <span class="kw">in</span> <span class="bu">range</span>(<span class="dv">1</span>, <span class="dv">101</span>):</span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>    largest <span class="op">=</span> <span class="bu">max</span>(largest, theMap.get(i, <span class="op">-</span>inf))</span></code></pre></div>
<p>The <code class="sourceCode default">get</code> member of Python’s
dictionary type looks up the supplied key (first argument). If the key
exists in the dictionary, <code class="sourceCode default">get</code>
returns the corresponding value; otherwise,
<code class="sourceCode default">get</code> returns the specified
alternative value (second argument).</p>
<p>In this paper, I propose a
<code class="sourceCode default">get</code> member function for
<code class="sourceCode default">std::map</code> and
<code class="sourceCode default">std::unordered_map</code> similar to
the <code class="sourceCode default">get</code> member in Python
dictionaries. Because C++ does not have a
<code class="sourceCode default">None</code> value like Python’s,
<code class="sourceCode default">get</code> returns an
<code class="sourceCode default">optional</code> instead and delegates
the construction of an alternative return value to the
<code class="sourceCode default">optional</code>.</p>
<h1 data-number="4" id="proposed-feature"><span class="header-section-number">4</span> Proposed Feature<a href="#proposed-feature" class="self-link"></a></h1>
<h2 data-number="4.1" id="overview"><span class="header-section-number">4.1</span> Overview<a href="#overview" class="self-link"></a></h2>
<p>What’s desired is a simple expression that, given a key, returns the
mapped value if the key exists in a specific map and a user-supplied
<em>alternative value</em> if the key does not exist. The proposed
feature is a <code class="sourceCode default">get</code> member function
for <code class="sourceCode default">map</code> and
<code class="sourceCode default">unordered_map</code> that returns
<code class="sourceCode default">optional&lt;T&amp;&gt;</code> (or, for
a <code class="sourceCode default">const</code> map,
<code class="sourceCode default">optional&lt;const T&amp;&gt;</code>):</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> Key, <span class="kw">class</span> T, <span class="kw">class</span> Compare <span class="op">=</span> less<span class="op">&lt;</span>Key<span class="op">&gt;</span>,</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>         <span class="kw">class</span> Allocator <span class="op">=</span> allocator<span class="op">&lt;</span>pair<span class="op">&lt;</span><span class="kw">const</span> Key, T<span class="op">&gt;&gt;&gt;</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> map <span class="op">{</span></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>  <span class="co">// ...</span></span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>  optional<span class="op">&lt;</span>      mapped_type<span class="op">&amp;&gt;</span> get<span class="op">(</span><span class="kw">const</span> key_type<span class="op">&amp;</span> k<span class="op">)</span>;</span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a>  optional<span class="op">&lt;</span><span class="kw">const</span> mapped_type<span class="op">&amp;&gt;</span> get<span class="op">(</span><span class="kw">const</span> key_type<span class="op">&amp;</span> k<span class="op">)</span> <span class="kw">const</span>;</span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a>  <span class="co">//...</span></span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code></pre></div>
<p>These functions depend on having an
<code class="sourceCode default">optional</code> template that can be
instantiated with reference types, as proposed in <span class="citation" data-cites="P2988R3">[<a href="#ref-P2988R3" role="doc-biblioref">P2988R3</a>]</span>.</p>
<p>Using this feature, the earlier example could be rewritten:</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="dt">double</span> negative_inf <span class="op">=</span> <span class="op">-</span>std<span class="op">::</span>numeric_limits<span class="op">&lt;</span><span class="dt">double</span><span class="op">&gt;::</span>infinity<span class="op">()</span>;</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a><span class="dt">double</span> largest <span class="op">=</span> negative_inf;</span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span> <span class="op">(</span><span class="dt">int</span> i <span class="op">=</span> <span class="dv">1</span>; i <span class="op">&lt;=</span> <span class="dv">100</span>; <span class="op">++</span>i<span class="op">)</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>  largest <span class="op">=</span> std<span class="op">::</span>max<span class="op">(</span>largest, theMap<span class="op">.</span>get<span class="op">(</span>i<span class="op">).</span>value_or<span class="op">(</span>negative_inf<span class="op">))</span>;</span></code></pre></div>
<h2 data-number="4.2" id="returning-a-different-but-compatible-reference-type"><span class="header-section-number">4.2</span> Returning a Different but
Compatible Reference Type<a href="#returning-a-different-but-compatible-reference-type" class="self-link"></a></h2>
<p>The return value of <code class="sourceCode default">value_or</code>
is <code class="sourceCode default">T&amp;</code> (as proposed in <span class="citation" data-cites="P2988R3">[<a href="#ref-P2988R3" role="doc-biblioref">P2988R3</a>]</span>). That means that the returned
value can be modified, which can be very useful even though the
modification does not always affect the
<code class="sourceCode default">map</code>:</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>std<span class="op">::</span>map<span class="op">&lt;</span>std<span class="op">::</span>string, <span class="dt">int</span><span class="op">&gt;</span> theMap<span class="op">{</span> <span class="op">...</span> <span class="op">}</span>;</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a><span class="co">// Increment the entries matching `names` but only if they are already in `theMap`.</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span> <span class="op">(</span><span class="kw">const</span> std<span class="op">:</span>string<span class="op">&amp;</span> name <span class="op">:</span> names<span class="op">)</span> <span class="op">{</span></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> temp <span class="op">=</span> <span class="dv">0</span>;</span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>  <span class="op">++</span>theMap<span class="op">.</span>get<span class="op">(</span>name<span class="op">).</span>value_or<span class="op">(</span>temp<span class="op">)</span>;  <span class="co">// increment through reference</span></span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a>  <span class="co">// Possibly-modified value of `temp` is discarded.</span></span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Sometimes, however, the definition of
<code class="sourceCode default">value_or</code> for
<code class="sourceCode default">optional&lt;T&amp;&gt;</code> described
in <span class="citation" data-cites="P2988R3">[<a href="#ref-P2988R3" role="doc-biblioref">P2988R3</a>]</span> is difficult to use. If
<code class="sourceCode default">T</code> is non-const, a valid-looking
and useful call could be rejected by the compiler:</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">const</span> <span class="dt">int</span> zero <span class="op">=</span> <span class="dv">0</span>;</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>std<span class="op">::</span>optional<span class="op">&lt;</span><span class="dt">int</span><span class="op">&amp;&gt;</span> x;</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> <span class="dt">int</span><span class="op">&amp;</span> r1 <span class="op">=</span> x<span class="op">.</span>value_or<span class="op">(</span>zero<span class="op">)</span>;  <span class="co">// Error: `const int&amp;` not convertible to `int&amp;`</span></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> <span class="dt">int</span><span class="op">&amp;</span> r2 <span class="op">=</span> std<span class="op">::</span>optional<span class="op">&lt;</span><span class="kw">const</span> <span class="dt">int</span><span class="op">&amp;&gt;(</span>x<span class="op">).</span>value_or<span class="op">(</span>zero<span class="op">)</span>;  <span class="co">// OK</span></span></code></pre></div>
<p>The error when constructing
<code class="sourceCode default">r1</code> is annoying, and the
workaround for <code class="sourceCode default">r2</code> is inelegant.
Having <code class="sourceCode default">optional&lt;T&amp;&gt;::value_or(U&amp;&amp;)</code>
return an lvalue of type <code class="sourceCode default">common_reference_t&lt;T&amp;, U&gt;</code>
would be much more convenient and would remain safe. Modifying
<code class="sourceCode default">value_or</code> in this way would allow
not only <code class="sourceCode default">const</code> lvalue arguments,
but also base classes of <code class="sourceCode default">T</code>:</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="kw">struct</span> Base <span class="op">{</span> <span class="op">...</span> <span class="op">}</span></span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> Derived <span class="op">:</span> Base <span class="op">{</span> <span class="op">...</span> <span class="op">}</span>;</span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>Base alt<span class="op">{</span> <span class="op">...</span> <span class="op">}</span>;</span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a>std<span class="op">::</span>opt<span class="op">&lt;</span>Derived<span class="op">&amp;&gt;</span> theOpt;</span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span><span class="op">&amp;</span> ref <span class="op">=</span> theOpt<span class="op">.</span>value_or<span class="op">(</span>alt<span class="op">)</span>;  <span class="co">// `ref` has type `Base&amp;`.</span></span></code></pre></div>
<p>This change to
<code class="sourceCode default">optional&lt;T&amp;&gt;::value_or</code>
has been suggested to the authors of P2988 and is also part of the
wording in this paper.</p>
<h2 data-number="4.3" id="returning-an-rvalue"><span class="header-section-number">4.3</span> Returning an Rvalue<a href="#returning-an-rvalue" class="self-link"></a></h2>
<p>Revisiting the earlier example for finding the largest entry in a
range, we note that, although
<code class="sourceCode default">value_or</code> works when passed an
lvalue,</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>  largest <span class="op">=</span> std<span class="op">::</span>max<span class="op">(</span>largest, theMap<span class="op">.</span>get<span class="op">(</span>i<span class="op">).</span>value_or<span class="op">(</span><strong>negative_inf</strong><span class="op">))</span>;</span></code></pre></div>
<p>the following code will not compile, even though it appears to be
equivalent:</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>  largest <span class="op">=</span> std<span class="op">::</span>max<span class="op">(</span>largest, theMap<span class="op">.</span>get<span class="op">(</span>i<span class="op">).</span>value_or<span class="op">(</span><strong>-std::numeric_limits<double>::infinity()</strong><span class="op">)</span>;</span></code></pre></div>
<p>The problem is that when an
<code class="sourceCode default">optional</code> holds a reference, the
argument to <code class="sourceCode default">value_or</code> must be an
lvalue of compatible type, whereas
<code class="sourceCode default">infinity()</code> returns an rvalue.
Moreover, even for an <code class="sourceCode default">optional</code>
that holds a nonreference,
<code class="sourceCode default">value_or</code> accepts only a single
argument rather than an
<code class="sourceCode default">emplace</code>-like list of constructor
arguments, potentially requiring that the return value be first
constructed, then moved (or worse, copied). Both problems are solved
with an additional <code class="sourceCode default">or_construct</code>
member function that has a variadic list of constructor arguments and
returns an rvalue by default, regardless of whether
<code class="sourceCode default">T</code> is a reference:</p>
<div class="sourceCode" id="cb14"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> U <span class="op">=</span> remove_cvref_t<span class="op">&lt;</span>T<span class="op">&gt;</span>, <span class="kw">class</span><span class="op">...</span> Args<span class="op">&gt;</span></span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>  U or_construct<span class="op">(</span>Args<span class="op">&amp;&amp;...</span> args<span class="op">)</span>;</span>
<span id="cb14-3"><a href="#cb14-3" 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">=</span> remove_cvref_t<span class="op">&lt;</span>T<span class="op">&gt;</span>, <span class="kw">class</span><span class="op">...</span> Args<span class="op">&gt;</span></span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>  U or_construct<span class="op">(</span>Args<span class="op">&amp;&amp;...</span> args<span class="op">)</span> <span class="kw">const</span>;</span></code></pre></div>
<p>The return value for
<code class="sourceCode default">or_construct</code> is constructed from
the <code class="sourceCode default">optional</code> value if
<code class="sourceCode default">has_value()</code> is true; otherwise,
it is constructed from <code class="sourceCode default">std::forward&lt;Args&gt;(args)...</code>.</p>
<p>Using <code class="sourceCode default">or_construct</code> instead of
<code class="sourceCode default">value_or</code> would yield this
working 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="dt">double</span> largest <span class="op">=</span> <span class="op">-</span>std<span class="op">::</span>numeric_limits<span class="op">&lt;</span><span class="dt">double</span><span class="op">&gt;::</span>infinity<span class="op">()</span>;</span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span> <span class="op">(</span><span class="dt">int</span> i <span class="op">=</span> <span class="dv">1</span>; i <span class="op">&lt;=</span> <span class="dv">100</span>; <span class="op">++</span>i<span class="op">)</span></span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>  largest <span class="op">=</span> std<span class="op">::</span>max<span class="op">(</span>largest,</span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a>                     theMap<span class="op">.</span>get<span class="op">(</span>i<span class="op">).</span><strong>or_construct</strong><span class="op">(-</span>std<span class="op">::</span>numeric_limits<span class="op">&lt;</span><span class="dt">double</span><span class="op">&gt;::</span>infinity<span class="op">()))</span>;</span></code></pre></div>
<h2 data-number="4.4" id="returning-a-type-other-than-mapped_type"><span class="header-section-number">4.4</span> Returning a Type Other Than
<code class="sourceCode default">mapped_type</code><a href="#returning-a-type-other-than-mapped_type" class="self-link"></a></h2>
<p>Although the return type of
<code class="sourceCode default">optional&lt;T&gt;::or_construct</code>
defaults to <code class="sourceCode default">T</code>, the user can
explicitly specify a different return type. This feature is useful when
the desired type is <em>convertible from</em>
<code class="sourceCode default">T</code> and where a more efficient
construction is possible for the alternative value. An emblematic
example is <code class="sourceCode default">std::string_view</code>.
Constructing a <code class="sourceCode default">string_view</code>
directly from a <code class="sourceCode default">char</code> array or
directly from an <code class="sourceCode default">std::string</code> is
efficient, but first converting a
<code class="sourceCode default">char</code> array to
<code class="sourceCode default">std::string</code> <em>and then</em>
constructing a <code class="sourceCode default">string_view</code> from
the resulting <code class="sourceCode default">string</code> is
inefficient. By specifying
<code class="sourceCode default">std::string_view</code> as the return
type, <code class="sourceCode default">or_construct</code> can be called
with <code class="sourceCode default">std::string</code> as
<code class="sourceCode default">T</code> and
<code class="sourceCode default">char[]</code> as the alternative value,
without generating temporary objects:</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>std<span class="op">::</span>optional<span class="op">&lt;</span>std<span class="op">::</span>string<span class="op">&gt;</span> theOpt;</span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a>std<span class="op">::</span>string_view sv1 <span class="op">=</span> theOpt<span class="op">.</span>or_construct<span class="op">&lt;</span>std<span class="op">::</span>string_view<span class="op">&gt;(</span><span class="st">&quot;empty&quot;</span><span class="op">)</span>;</span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a>std<span class="op">::</span>map<span class="op">&lt;</span><span class="dt">int</span>, std<span class="op">::</span>string<span class="op">&gt;</span> theMap<span class="op">{</span> <span class="op">...</span> <span class="op">}</span>;</span>
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a>std<span class="op">::</span>string_view sv2 <span class="op">=</span> theMap<span class="op">.</span>get<span class="op">(</span>key<span class="op">).</span>or_construct<span class="op">&lt;</span>std<span class="op">::</span>string_view<span class="op">&gt;(</span><span class="st">&quot;none&quot;</span><span class="op">)</span>;</span></code></pre></div>
<p>The example above creates the resulting
<code class="sourceCode default">std::string_view</code> objects either
from the <code class="sourceCode default">std::string</code> stored in
the <code class="sourceCode default">optional</code> or from the
<code class="sourceCode default">const char[]</code> passed as the
alternative value, without creating an intervening
<code class="sourceCode default">std::string</code>. Not only would
conversion to an intermediate
<code class="sourceCode default">std::string</code> be inefficient, such
a conversion would create problems with object lifetimes:</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="co">// Bug (silent): dangling reference constructing `string_view` from temporary `string`</span></span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a>std<span class="op">::</span>string_view sv1 <span class="op">=</span> theOpt<span class="op">.</span>or_construct<span class="op">(</span><span class="st">&quot;none&quot;</span><span class="op">)</span>;</span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a><span class="co">// Error (ill formed): cannot convert `char[]` rvalue to `string` lvalue</span></span>
<span id="cb17-5"><a href="#cb17-5" aria-hidden="true" tabindex="-1"></a>std<span class="op">::</span>string_view sv2 <span class="op">=</span> theMap<span class="op">.</span>get<span class="op">(</span>key<span class="op">).</span>value_or<span class="op">(</span><span class="st">&quot;none&quot;</span><span class="op">)</span>;</span></code></pre></div>
<p>If the specified return type is a reference, then
<code class="sourceCode default">or_construct</code> behaves much like
<code class="sourceCode default">value_or</code> except that the return
type is exactly the specified type, rather than the deduced common
reference type between <code class="sourceCode default">T&amp;</code>
and the alternative argument:</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>std<span class="op">::</span>optional<span class="op">&lt;</span><span class="dt">int</span><span class="op">&amp;&gt;</span> theOpt;</span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> <span class="dt">int</span> zero <span class="op">=</span> <span class="dv">0</span>;</span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span><span class="op">&amp;</span> v1 <span class="op">=</span> theOpt<span class="op">.</span>value_or<span class="op">(</span>zero<span class="op">)</span>;                 <span class="co">// OK</span></span>
<span id="cb18-5"><a href="#cb18-5" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span><span class="op">&amp;</span> v2 <span class="op">=</span> theOpt<span class="op">.</span>or_construct<span class="op">&lt;</span><span class="dt">int</span><span class="op">&amp;&gt;(</span>zero<span class="op">)</span>;       <span class="co">// Error: `const` mismatch</span></span>
<span id="cb18-6"><a href="#cb18-6" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span><span class="op">&amp;</span> v3 <span class="op">=</span> theOpt<span class="op">.</span>or_construct<span class="op">&lt;</span><span class="kw">const</span> <span class="dt">int</span><span class="op">&amp;&gt;(</span>zero<span class="op">)</span>; <span class="co">// OK</span></span></code></pre></div>
<h1 data-number="5" id="before-and-after-comparisons"><span class="header-section-number">5</span> Before and After Comparisons<a href="#before-and-after-comparisons" class="self-link"></a></h1>
<p>The following table shows how operations are simplified using the
proposed new member functions. In these examples,
<code class="sourceCode default">K</code>,
<code class="sourceCode default">T</code>, and
<code class="sourceCode default">U</code> are object types;
<code class="sourceCode default">m</code> is an object of (possibly
<code class="sourceCode default">const</code>)
<code class="sourceCode default">std::map&lt;K, T&gt;</code>,
<code class="sourceCode default">unordered_map&lt;K, T&gt;</code>, or
<code class="sourceCode default">flat_map&lt;K, T&gt;</code>;
<code class="sourceCode default">k</code> is a value compatible with
<code class="sourceCode default">K</code>;
<code class="sourceCode default">v</code> is an lvalue of type (possibly
<code class="sourceCode default">const</code>)
<code class="sourceCode default">T</code>; and
<code class="sourceCode default">a1..aN</code> are arguments that can
used to construct an object of type
<code class="sourceCode default">T</code>.</p>
<table>
<thead>
<tr class="header">
<th><div style="text-align:center">
<strong>Before</strong>
</div></th>
<th><div style="text-align:center">
<strong>After</strong>
</div></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><div>

<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">auto</span> iter <span class="op">=</span> m<span class="op">.</span>find<span class="op">(</span>k<span class="op">)</span>;</span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a>T x <span class="op">=</span> iter <span class="op">==</span> m<span class="op">.</span>end<span class="op">()</span> <span class="op">?</span> T<span class="op">{}</span> <span class="op">:</span> iter<span class="op">-&gt;</span>second;</span></code></pre></div>

</div></td>
<td><div>

<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>T x <span class="op">=</span> m<span class="op">.</span>get<span class="op">(</span>k<span class="op">).</span>or_construct<span class="op">()</span>;</span></code></pre></div>

</div></td>
</tr>
<tr class="even">
<td><div>

<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">auto</span> iter <span class="op">=</span> m<span class="op">.</span>find<span class="op">(</span>k<span class="op">)</span>;</span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a>T x <span class="op">=</span> iter <span class="op">==</span> m<span class="op">.</span>end<span class="op">()</span> <span class="op">?</span></span>
<span id="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a>    T<span class="op">(</span>a1<span class="op">...</span>aN<span class="op">)</span> <span class="op">:</span> iter<span class="op">-&gt;</span>second;</span></code></pre></div>

</div></td>
<td><div>

<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>T x <span class="op">=</span> m<span class="op">.</span>get<span class="op">(</span>k<span class="op">).</span>or_construct<span class="op">(</span>a1<span class="op">...</span>aN<span class="op">)</span>;</span></code></pre></div>

</div></td>
</tr>
<tr class="odd">
<td><div>

<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">auto</span> iter <span class="op">=</span> m<span class="op">.</span>find<span class="op">(</span>k<span class="op">)</span>;</span>
<span id="cb23-2"><a href="#cb23-2" aria-hidden="true" tabindex="-1"></a>T<span class="op">&amp;</span> x <span class="op">=</span> iter <span class="op">==</span> m<span class="op">.</span>end<span class="op">()</span> <span class="op">?</span> v <span class="op">:</span> iter<span class="op">-&gt;</span>second;</span></code></pre></div>

</div></td>
<td><div>

<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>T<span class="op">&amp;</span> x <span class="op">=</span> m<span class="op">.</span>get<span class="op">(</span>k<span class="op">.</span>value_or<span class="op">(</span>v<span class="op">))</span>;</span></code></pre></div>

</div></td>
</tr>
<tr class="even">
<td><div>

<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>map<span class="op">&lt;</span>K, vector<span class="op">&lt;</span>U<span class="op">&gt;&gt;</span> m<span class="op">{</span> <span class="op">...</span> <span class="op">}</span>;</span>
<span id="cb25-2"><a href="#cb25-2" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> iter <span class="op">=</span> m<span class="op">.</span>find<span class="op">(</span>k<span class="op">)</span>;</span>
<span id="cb25-3"><a href="#cb25-3" aria-hidden="true" tabindex="-1"></a>span<span class="op">&lt;</span>U<span class="op">&gt;</span> x <span class="op">=</span> iter <span class="op">==</span> m<span class="op">.</span>end<span class="op">()</span> <span class="op">?</span></span>
<span id="cb25-4"><a href="#cb25-4" aria-hidden="true" tabindex="-1"></a>    span<span class="op">&lt;</span>U<span class="op">&gt;{}</span> <span class="op">:</span> iter<span class="op">-&gt;</span>second;</span></code></pre></div>

</div></td>
<td><div>

<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>map<span class="op">&lt;</span>K, vector<span class="op">&lt;</span>U<span class="op">&gt;&gt;</span> m<span class="op">{</span> <span class="op">...</span> <span class="op">}</span>;</span>
<span id="cb26-2"><a href="#cb26-2" aria-hidden="true" tabindex="-1"></a>span<span class="op">&lt;</span>U<span class="op">&gt;</span> x <span class="op">=</span> m<span class="op">.</span>get<span class="op">(</span>k<span class="op">).</span>or_construct<span class="op">&lt;</span>span<span class="op">&lt;</span>U<span class="op">&gt;&gt;()</span>;</span></code></pre></div>

</div></td>
</tr>
<tr class="odd">
<td><div>

<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>map<span class="op">&lt;</span>K, vector<span class="op">&lt;</span>U<span class="op">&gt;&gt;</span> m<span class="op">{</span> <span class="op">...</span> <span class="op">}</span>;</span>
<span id="cb27-2"><a href="#cb27-2" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> array<span class="op">&lt;</span>U, N<span class="op">&gt;</span> preset<span class="op">{</span> <span class="op">...</span> <span class="op">}</span>;</span>
<span id="cb27-3"><a href="#cb27-3" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> iter <span class="op">=</span> m<span class="op">.</span>find<span class="op">(</span>k<span class="op">)</span>;</span>
<span id="cb27-4"><a href="#cb27-4" aria-hidden="true" tabindex="-1"></a>span<span class="op">&lt;</span><span class="kw">const</span> U<span class="op">&gt;</span> x <span class="op">=</span> iter <span class="op">==</span> m<span class="op">.</span>end<span class="op">()</span> <span class="op">?</span></span>
<span id="cb27-5"><a href="#cb27-5" aria-hidden="true" tabindex="-1"></a>    span<span class="op">&lt;</span><span class="kw">const</span> U<span class="op">&gt;(</span>preset<span class="op">)</span> <span class="op">:</span> iter<span class="op">-&gt;</span>second;</span></code></pre></div>

</div></td>
<td><div>

<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>map<span class="op">&lt;</span>K, vector<span class="op">&lt;</span>U<span class="op">&gt;&gt;</span> m<span class="op">{</span> <span class="op">...</span> <span class="op">}</span>;</span>
<span id="cb28-2"><a href="#cb28-2" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> array<span class="op">&lt;</span>U, N<span class="op">&gt;</span> preset<span class="op">{</span> <span class="op">...</span> <span class="op">}</span>;</span>
<span id="cb28-3"><a href="#cb28-3" aria-hidden="true" tabindex="-1"></a>span<span class="op">&lt;</span><span class="kw">const</span> U<span class="op">&gt;</span> x <span class="op">=</span></span>
<span id="cb28-4"><a href="#cb28-4" aria-hidden="true" tabindex="-1"></a>  m<span class="op">.</span>get<span class="op">(</span>k<span class="op">).</span>or_construct<span class="op">&lt;</span>span<span class="op">&lt;</span><span class="kw">const</span> U<span class="op">&gt;&gt;(</span>preset<span class="op">)</span>;</span></code></pre></div>

</div></td>
</tr>
<tr class="even">
<td><div>

<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>unordered_map<span class="op">&lt;</span>K, U<span class="op">*&gt;</span> m<span class="op">{</span> <span class="op">...</span> <span class="op">}</span>;</span>
<span id="cb29-2"><a href="#cb29-2" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> iter <span class="op">=</span> m<span class="op">.</span>find<span class="op">(</span>k<span class="op">)</span>;</span>
<span id="cb29-3"><a href="#cb29-3" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> <span class="op">(</span>iter <span class="op">!=</span> m<span class="op">.</span>end<span class="op">())</span> <span class="op">{</span></span>
<span id="cb29-4"><a href="#cb29-4" aria-hidden="true" tabindex="-1"></a>  U<span class="op">*</span> p <span class="op">=</span> iter<span class="op">-&gt;</span>second;</span>
<span id="cb29-5"><a href="#cb29-5" aria-hidden="true" tabindex="-1"></a>  <span class="co">// ...</span></span>
<span id="cb29-6"><a href="#cb29-6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>

</div></td>
<td><div>

<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>unordered_map<span class="op">&lt;</span>K, U<span class="op">*&gt;</span> m<span class="op">{</span> <span class="op">...</span> <span class="op">}</span>;</span>
<span id="cb30-2"><a href="#cb30-2" aria-hidden="true" tabindex="-1"></a>U<span class="op">*</span> p <span class="op">=</span> m<span class="op">.</span>get<span class="op">(</span>k<span class="op">).</span>or_construct<span class="op">(</span><span class="kw">nullptr</span><span class="op">)</span>;</span>
<span id="cb30-3"><a href="#cb30-3" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> <span class="op">(</span>p<span class="op">)</span> <span class="op">{</span></span>
<span id="cb30-4"><a href="#cb30-4" aria-hidden="true" tabindex="-1"></a>  <span class="co">// ...</span></span>
<span id="cb30-5"><a href="#cb30-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>

</div></td>
</tr>
<tr class="odd">
<td><div>

<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">auto</span> iter <span class="op">=</span> m<span class="op">.</span>find<span class="op">(</span>k<span class="op">)</span>;</span>
<span id="cb31-2"><a href="#cb31-2" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> <span class="op">(</span>iter <span class="op">!=</span> m<span class="op">.</span>end<span class="op">())</span> <span class="op">{</span></span>
<span id="cb31-3"><a href="#cb31-3" aria-hidden="true" tabindex="-1"></a>  T<span class="op">&amp;</span> r <span class="op">=</span> iter<span class="op">-&gt;</span>second;</span>
<span id="cb31-4"><a href="#cb31-4" aria-hidden="true" tabindex="-1"></a>  <span class="co">// ...</span></span>
<span id="cb31-5"><a href="#cb31-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>

</div></td>
<td><div>

<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">auto</span> q <span class="op">=</span> m<span class="op">.</span>get<span class="op">(</span>k<span class="op">)</span>;</span>
<span id="cb32-2"><a href="#cb32-2" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> <span class="op">(</span>q<span class="op">)</span> <span class="op">{</span></span>
<span id="cb32-3"><a href="#cb32-3" aria-hidden="true" tabindex="-1"></a>  T<span class="op">&amp;</span> r <span class="op">=</span> <span class="op">*</span>q;</span>
<span id="cb32-4"><a href="#cb32-4" aria-hidden="true" tabindex="-1"></a>  <span class="co">// ...</span></span>
<span id="cb32-5"><a href="#cb32-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>

</div></td>
</tr>
</tbody>
</table>
<h1 data-number="6" id="alternatives-considered"><span class="header-section-number">6</span> Alternatives Considered<a href="#alternatives-considered" class="self-link"></a></h1>
<h2 data-number="6.1" id="names"><span class="header-section-number">6.1</span> Names<a href="#names" class="self-link"></a></h2>
<p>The name <code class="sourceCode default">map::get</code> is borrowed
from the Python dictionary member of the same name. Other names
considered were <code class="sourceCode default">get_optional</code>,
<code class="sourceCode default">lookup</code>, and
<code class="sourceCode default">lookup_optional</code>. The
<code class="sourceCode default">get</code> name was selected for
brevity and familiarity, but
<code class="sourceCode default">lookup</code> is also concise and is a
reasonable alternative.</p>
<p>The name
<code class="sourceCode default">optional&lt;T&gt;::or_construct</code>
was selected for consistency with the monadic operations
<code class="sourceCode default">and_then</code> and
<code class="sourceCode default">or_else</code>. However, we might
consider <code class="sourceCode default">value_or_construct</code> as
an intuitive extension of
<code class="sourceCode default">value_or</code>.</p>
<h2 data-number="6.2" id="build-get-value-or-return-alternative-functionality-directly-into-map"><span class="header-section-number">6.2</span> Build
Get-Value-or-Return-Alternative Functionality Directly into
<code class="sourceCode default">map</code><a href="#build-get-value-or-return-alternative-functionality-directly-into-map" class="self-link"></a></h2>
<p>Version R0 of this paper proposed
<code class="sourceCode default">get</code>,
<code class="sourceCode default">get_ref</code>, and
<code class="sourceCode default">get_as</code> member functions that
would look up a key and return the corresponding value (or a reference
to the corresponding value) or else construct an alternative from the
nonkey arguments without involving
<code class="sourceCode default">optional&lt;T&amp;&gt;</code>:</p>
<div class="sourceCode" id="cb33"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb33-1"><a href="#cb33-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span><span class="op">...</span> Args<span class="op">&gt;</span></span>
<span id="cb33-2"><a href="#cb33-2" aria-hidden="true" tabindex="-1"></a>  mapped_type get<span class="op">(</span><span class="kw">const</span> key_type<span class="op">&amp;</span> key, Args<span class="op">&amp;&amp;...</span> args<span class="op">)</span> <span class="kw">const</span>;</span>
<span id="cb33-3"><a href="#cb33-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb33-4"><a href="#cb33-4" aria-hidden="true" tabindex="-1"></a><span class="co">// return by reference</span></span>
<span id="cb33-5"><a href="#cb33-5" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> Arg<span class="op">&gt;</span></span>
<span id="cb33-6"><a href="#cb33-6" aria-hidden="true" tabindex="-1"></a>  common_reference_t<span class="op">&lt;</span>mapped_type<span class="op">&amp;</span>,       Arg<span class="op">&gt;</span> get_ref<span class="op">(</span><span class="kw">const</span> key_type<span class="op">&amp;</span> key, Arg<span class="op">&amp;&amp;</span> ref<span class="op">)</span>;</span>
<span id="cb33-7"><a href="#cb33-7" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> Arg<span class="op">&gt;</span></span>
<span id="cb33-8"><a href="#cb33-8" aria-hidden="true" tabindex="-1"></a>  common_reference_t<span class="op">&lt;</span><span class="kw">const</span> mapped_type<span class="op">&amp;</span>, Arg<span class="op">&gt;</span> get_ref<span class="op">(</span><span class="kw">const</span> key_type<span class="op">&amp;</span> key, Arg<span class="op">&amp;&amp;</span> ref<span class="op">)</span> <span class="kw">const</span>;</span>
<span id="cb33-9"><a href="#cb33-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb33-10"><a href="#cb33-10" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> U, <span class="kw">class</span><span class="op">...</span> Args<span class="op">&gt;</span></span>
<span id="cb33-11"><a href="#cb33-11" aria-hidden="true" tabindex="-1"></a>  U get_as<span class="op">(</span><span class="kw">const</span> key_type<span class="op">&amp;</span> key, Args<span class="op">&amp;&amp;...</span> args<span class="op">)</span>;</span>
<span id="cb33-12"><a href="#cb33-12" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> U, <span class="kw">class</span><span class="op">...</span> Args<span class="op">&gt;</span></span>
<span id="cb33-13"><a href="#cb33-13" aria-hidden="true" tabindex="-1"></a>  U get_as<span class="op">(</span><span class="kw">const</span> key_type<span class="op">&amp;</span> key, Args<span class="op">&amp;&amp;...</span> args<span class="op">)</span> <span class="kw">const</span>;</span></code></pre></div>
<p>LEWGI members later pointed out that the
<code class="sourceCode default">get_as</code> functionality could be
merged into <code class="sourceCode default">get</code> by adding a
defaulted <code class="sourceCode default">U</code> parameter to
<code class="sourceCode default">get</code>:</p>
<div class="sourceCode" id="cb34"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb34-1"><a href="#cb34-1" 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">=</span> remove_cvref_t<span class="op">&lt;</span>T<span class="op">&gt;</span>, <span class="kw">class</span><span class="op">...</span> Args<span class="op">&gt;</span></span>
<span id="cb34-2"><a href="#cb34-2" aria-hidden="true" tabindex="-1"></a>  U get<span class="op">(</span><span class="kw">const</span> key_type<span class="op">&amp;</span> key, Args<span class="op">&amp;&amp;...</span> args<span class="op">)</span>;</span>
<span id="cb34-3"><a href="#cb34-3" 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">=</span> remove_cvref_t<span class="op">&lt;</span>T<span class="op">&gt;</span>, <span class="kw">class</span><span class="op">...</span> Args<span class="op">&gt;</span></span>
<span id="cb34-4"><a href="#cb34-4" aria-hidden="true" tabindex="-1"></a>  U get<span class="op">(</span><span class="kw">const</span> key_type<span class="op">&amp;</span> key, Args<span class="op">&amp;&amp;...</span> args<span class="op">)</span> <span class="kw">const</span>;</span></code></pre></div>
<p>The following table shows the usage of the R0 design compared to the
currently proposed design.</p>
<table>
<thead>
<tr class="header">
<th><div style="text-align:center">
<strong>R0 Design (<code class="sourceCode default">get</code> Returns
<code class="sourceCode default">T</code>)</strong>
</div></th>
<th><div style="text-align:center">
<strong>Current Design (<code class="sourceCode default">get</code>
Returns
<code class="sourceCode default">optional&lt;T&amp;&gt;</code>)</strong>
</div></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><div>

<div class="sourceCode" id="cb35"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb35-1"><a href="#cb35-1" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> tval <span class="op">=</span> theMap<span class="op">.</span>get<span class="op">(</span>k<span class="op">)</span>;</span></code></pre></div>

</div></td>
<td><div>

<div class="sourceCode" id="cb36"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb36-1"><a href="#cb36-1" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> tval <span class="op">=</span> theMap<span class="op">.</span>get<span class="op">(</span>k<span class="op">).</span>or_construct<span class="op">()</span>;</span></code></pre></div>

</div></td>
</tr>
<tr class="even">
<td><div>

<div class="sourceCode" id="cb37"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb37-1"><a href="#cb37-1" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> tval <span class="op">=</span> theMap<span class="op">.</span>get<span class="op">(</span>k, cT1, cT2<span class="op">)</span>;</span></code></pre></div>

</div></td>
<td><div>

<div class="sourceCode" id="cb38"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb38-1"><a href="#cb38-1" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> tval <span class="op">=</span></span>
<span id="cb38-2"><a href="#cb38-2" aria-hidden="true" tabindex="-1"></a>    theMap<span class="op">.</span>get<span class="op">(</span>k<span class="op">).</span>or_construct<span class="op">(</span>cT1, cT2<span class="op">)</span>;</span></code></pre></div>

</div></td>
</tr>
<tr class="odd">
<td><div>

<div class="sourceCode" id="cb39"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb39-1"><a href="#cb39-1" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span><span class="op">&amp;</span> tref <span class="op">=</span> theMap<span class="op">.</span>get_ref<span class="op">(</span>k, lvalue<span class="op">)</span>;</span></code></pre></div>

</div></td>
<td><div>

<div class="sourceCode" id="cb40"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb40-1"><a href="#cb40-1" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span><span class="op">&amp;</span> tref <span class="op">=</span> theMap<span class="op">.</span>get<span class="op">(</span>k<span class="op">).</span>value_or<span class="op">(</span>lvalue<span class="op">)</span>;</span></code></pre></div>

</div></td>
</tr>
<tr class="even">
<td><div>

<div class="sourceCode" id="cb41"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb41-1"><a href="#cb41-1" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> uval <span class="op">=</span> theMap<span class="op">.</span>get_as<span class="op">&lt;</span>U<span class="op">&gt;(</span>k, cU1, cU2<span class="op">)</span>;</span></code></pre></div>

</div></td>
<td><div>

<div class="sourceCode" id="cb42"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb42-1"><a href="#cb42-1" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> uval <span class="op">=</span></span>
<span id="cb42-2"><a href="#cb42-2" aria-hidden="true" tabindex="-1"></a>    theMap<span class="op">.</span>get<span class="op">(</span>k<span class="op">).</span>or_construct<span class="op">&lt;</span>U<span class="op">&gt;(</span>cU1, cU2<span class="op">)</span>;</span></code></pre></div>

</div></td>
</tr>
<tr class="odd">
<td><div>

<div class="sourceCode" id="cb43"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb43-1"><a href="#cb43-1" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> <span class="op">(</span><span class="kw">auto</span> opt <span class="op">=</span> theMap<span class="op">.</span>get_as<span class="op">&lt;</span>std<span class="op">::</span>optional<span class="op">&lt;</span>T<span class="op">&amp;&gt;&gt;(</span>k<span class="op">)</span>;</span>
<span id="cb43-2"><a href="#cb43-2" aria-hidden="true" tabindex="-1"></a>    opt<span class="op">)</span> <span class="op">{</span></span>
<span id="cb43-3"><a href="#cb43-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">auto</span><span class="op">&amp;</span> ref <span class="op">=</span> <span class="op">*</span>opt;</span>
<span id="cb43-4"><a href="#cb43-4" aria-hidden="true" tabindex="-1"></a>  <span class="co">// ...</span></span>
<span id="cb43-5"><a href="#cb43-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>

</div></td>
<td><div>

<div class="sourceCode" id="cb44"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb44-1"><a href="#cb44-1" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> <span class="op">(</span><span class="kw">auto</span> opt <span class="op">=</span> theMap<span class="op">.</span>get<span class="op">(</span>k<span class="op">)</span>; opt<span class="op">)</span> <span class="op">{</span></span>
<span id="cb44-2"><a href="#cb44-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">auto</span><span class="op">&amp;</span> ref <span class="op">=</span> <span class="op">*</span>opt;</span>
<span id="cb44-3"><a href="#cb44-3" aria-hidden="true" tabindex="-1"></a>  <span class="co">// ...</span></span>
<span id="cb44-4"><a href="#cb44-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>

</div></td>
</tr>
</tbody>
</table>
<p><strong>Advantages of the R0 Design Over the Current
Design</strong></p>
<ul>
<li>R0 provides more concise and readable calls to
<code class="sourceCode default">get</code> and
<code class="sourceCode default">get_ref</code> in many cases.</li>
<li>The desired return-value-if-present-else-return-alternative
functionality is all specified in one place in the R0 design, exactly
where a beginner would look for it.</li>
<li>R0 <code class="sourceCode default">map</code> and
<code class="sourceCode default">unordered_map</code> specification
changes would be independent of
<code class="sourceCode default">optional</code>.</li>
</ul>
<p><strong>Advantages of the Current Design Over the R0
Design</strong></p>
<ul>
<li>The current <code class="sourceCode default">get</code> provides a
direct indication, via a disengaged
<code class="sourceCode default">optional</code> return value, that the
key was not found.</li>
<li>By returning <code class="sourceCode default">optional</code>, the
current design can leverage all of the functionality of
<code class="sourceCode default">optional</code>, including
<code class="sourceCode default">value_or</code> and monadic operations.
Any future improvements to
<code class="sourceCode default">optional</code> could be accessed by
users of <code class="sourceCode default">map::get</code> without
modifying <code class="sourceCode default">map</code>.</li>
<li>The current version has a single observer
(<code class="sourceCode default">get</code>) compared to two observers
for R0 (<code class="sourceCode default">get</code> and
<code class="sourceCode default">get_ref</code>, assuming
<code class="sourceCode default">get_as</code> is merged into
<code class="sourceCode default">get</code>). Since each observer
requires four overloads (<code class="sourceCode default">const</code>
and non-<code class="sourceCode default">const</code>, each having a
<code class="sourceCode default">key_type</code> or templated
<code class="sourceCode default">K</code> parameter), the interface
simplification is noticeable.</li>
<li>The current specification of
<code class="sourceCode default">get</code> is simple to specify and
implement, making <code class="sourceCode default">get</code> easy to
add to nonstandard map-like containers and new standard containers such
as <code class="sourceCode default">flat_map</code>.</li>
<li>The current interface can be applied not only to associative
map-like containers, but to any indexable container, including
<code class="sourceCode default">vector</code> and
<code class="sourceCode default">deque</code>, should the committee
choose to do that.</li>
</ul>
<p>During the <a href="https://wiki.edg.com/bin/view/Wg21telecons2024/P3091#Library-Evolution-2024-02-27">2024-02-27
LEWGI (SG18) telecon</a>, unanimous consent was achieved for
<code class="sourceCode default">get</code> returning
<code class="sourceCode default">optional&lt;T&amp;&gt;</code> (known as
the Alternative Design in <span class="citation" data-cites="P3091R0">[<a href="#ref-P3091R0" role="doc-biblioref">P3091R0</a>]</span>):</p>
<blockquote>
<p>POLL: The alternative design with a smaller container API with
extensions to <code class="sourceCode default">std::optional</code>
should be pursued.</p>
</blockquote>
<table style="width:19%;">
<colgroup>
<col style="width: 4%" />
<col style="width: 4%" />
<col style="width: 2%" />
<col style="width: 4%" />
<col style="width: 4%" />
</colgroup>
<thead>
<tr class="header">
<th><div style="text-align:center">
<strong>SF</strong>
</div></th>
<th><div style="text-align:center">
<strong>WF</strong>
</div></th>
<th><div style="text-align:center">
<strong>N</strong>
</div></th>
<th><div style="text-align:center">
<strong>WA</strong>
</div></th>
<th><div style="text-align:center">
<strong>SA</strong>
</div></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>6</td>
<td>4</td>
<td>0</td>
<td>0</td>
<td>0</td>
</tr>
</tbody>
</table>
<h2 data-number="6.3" id="combine-optionaltvalue_or-and-optionaltor_construct"><span class="header-section-number">6.3</span> Combine
<code class="sourceCode default">optional&lt;T&gt;::value_or</code> and
<code class="sourceCode default">optional&lt;T&gt;::or_construct</code><a href="#combine-optionaltvalue_or-and-optionaltor_construct" class="self-link"></a></h2>
<p>Adding a variadic parameter list to
<code class="sourceCode default">value_or</code> so that more than one
constructor argument could be passed at once would be theoretically
possible and would obviate
<code class="sourceCode default">or_construct</code> as a separate
member. However, when <code class="sourceCode default">T</code> is a
reference, <span class="citation" data-cites="P2988R3">[<a href="#ref-P2988R3" role="doc-biblioref">P2988R3</a>]</span> says that
the return value of <code class="sourceCode default">value_or</code> is
also a reference. Passing multiple constructor arguments to
<code class="sourceCode default">value_or</code> requires returning an
rvalue. While automatically determining the value category (rvalue or
lvalue) returned by <code class="sourceCode default">value_or</code> is
theoretically possible, such a definition would be confusing, especially
to a human reader, who must analyze the code carefully to determine
whether non-<code class="sourceCode default">const</code> operations on
the returned entity might inadvertently change a value in the original
<code class="sourceCode default">optional</code>.</p>
<h2 data-number="6.4" id="lazy-evaluation-of-or_construct-argument"><span class="header-section-number">6.4</span> Lazy Evaluation of
<code class="sourceCode default">or_construct</code> Argument<a href="#lazy-evaluation-of-or_construct-argument" class="self-link"></a></h2>
<p>The map lookup functionality described in this paper was implemented
as free utility functions in <span class="citation" data-cites="Folly">[<a href="#ref-Folly" role="doc-biblioref">Folly</a>]</span>. Specifically, the <code class="sourceCode default">folly::map_default(<em>map</em>, <em>key</em>, <em>dflt</em>)</code>
function behaves similar to the
<code class="sourceCode default"><em>map</em>.get(<em>key</em>, <em>dflt</em>)</code>
function proposed in R0 of this paper. Folly, however, goes one step
further: If <code class="sourceCode default"><em>dflt</em></code> is a
functor taking no arguments and returns a value convertible to
<code class="sourceCode default">mapped_type</code>, then the functor is
invoked if and only if the key is not found in the map; i.e., the
alternative value is computed <em>lazily</em> when needed.</p>
<p>If such lazy evaluation is desired within the framework of this
proposal, the functionality would be added to
<code class="sourceCode default">optional&lt;T&gt;::or_construct</code>.
Although not directly related to map lookups, I would consider extending
this proposal accordingly.</p>
<h2 data-number="6.5" id="free-functions-instead-of-members"><span class="header-section-number">6.5</span> Free Functions Instead of
Members<a href="#free-functions-instead-of-members" class="self-link"></a></h2>
<p>Providing the functionality described in this paper is possible using
namespace-scope functions, without modifying
<code class="sourceCode default">std::map</code> and
<code class="sourceCode default">std::unordered_map</code>:</p>
<div class="sourceCode" id="cb45"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb45-1"><a href="#cb45-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> Map, <span class="kw">class</span> K, <span class="kw">class</span><span class="op">...</span> Args<span class="op">&gt;</span></span>
<span id="cb45-2"><a href="#cb45-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">typename</span> optional<span class="op">&lt;</span><span class="kw">typename</span> Map<span class="op">::</span>mapped_type<span class="op">&amp;&gt;</span> get<span class="op">(</span>Map<span class="op">&amp;</span> m, <span class="kw">const</span> K<span class="op">&amp;</span> k<span class="op">)</span>;</span>
<span id="cb45-3"><a href="#cb45-3" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> Map, <span class="kw">class</span> K, <span class="kw">class</span><span class="op">...</span> Args<span class="op">&gt;</span></span>
<span id="cb45-4"><a href="#cb45-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">typename</span> optional<span class="op">&lt;</span><span class="kw">const</span> <span class="kw">typename</span> Map<span class="op">::</span>mapped_type<span class="op">&amp;&gt;</span> get<span class="op">(</span><span class="kw">const</span> Map<span class="op">&amp;</span> m, <span class="kw">const</span> K<span class="op">&amp;</span> k<span class="op">)</span>;</span>
<span id="cb45-5"><a href="#cb45-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb45-6"><a href="#cb45-6" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> x <span class="op">=</span> get<span class="op">(</span>m, k<span class="op">).</span>value_or<span class="op">(</span>v<span class="op">)</span>;</span></code></pre></div>
<p>One benefit to this approach is that the namespace-scoped
<code class="sourceCode default">get</code> template can handle any
<em>map-like</em> dictionary type (i.e., a type having a
<code class="sourceCode default">mapped_type</code> and a
<code class="sourceCode default">find</code> method that returns an
<code class="sourceCode default">iterator</code> pointing to a key-value
<code class="sourceCode default">pair</code>). Such an approach,
however, has disadvantages.</p>
<ul>
<li>A global function is less intuitive because it puts
<code class="sourceCode default">get</code> outside of the map
interface.</li>
<li>The short name can cause ADL issues.</li>
<li>The <em>map-like</em> concept is novel and not used elsewhere in the
Standard. Whether many classes model this concept and would therefore
benefit from the generality is unclear.</li>
</ul>
<p>Moving the <code class="sourceCode default">construct_or</code>
functionality out of <code class="sourceCode default">optional</code>
makes even less sense given that only one
<code class="sourceCode default">optional</code> exists, so making any
core observer into a free function would offer no benefit.</p>
<h1 data-number="7" id="implementation-experience"><span class="header-section-number">7</span> Implementation Experience<a href="#implementation-experience" class="self-link"></a></h1>
<p>An implementation, with tests and usage examples, can be found at <a href="https://github.com/phalpern/WG21-halpern/tree/main/P3091-map_lookup">https://github.com/phalpern/WG21-halpern/tree/main/P3091-map_lookup</a>.</p>
<p>Some of the functionality can be found in Meta’s <span class="citation" data-cites="Folly">[<a href="#ref-Folly" role="doc-biblioref">Folly</a>]</span> library.</p>
<h1 data-number="8" id="wording"><span class="header-section-number">8</span> Wording<a href="#wording" class="self-link"></a></h1>
<p>The changes below clearly note whether they are relative to the
2023-12-18 Working Draft, <span class="citation" data-cites="N4971">[<a href="#ref-N4971" role="doc-biblioref">N4971</a>]</span>, or to the
paper proposing
<code class="sourceCode default">optional&lt;T&amp;&gt;</code>, <span class="citation" data-cites="P2988R3">[<a href="#ref-P2988R3" role="doc-biblioref">P2988R3</a>]</span>.</p>
<h2 data-number="8.1" id="feature-test-macros"><span class="header-section-number">8.1</span> Feature-Test Macros<a href="#feature-test-macros" class="self-link"></a></h2>
<p>To the list in <span>17.3.2
<a href="https://wg21.link/N4971#version.syn">[version.syn]</a><a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a></span>, add:</p>
<blockquote>
<div class="add" style="color: #006e28">
<p><code class="sourceCode default">#define __cpp_lib_map_get_optional yyyymmL // also in &lt;map&gt;, &lt;multimap&gt;</code></p>
</div>
</blockquote>
<p>and</p>
<blockquote>
<div class="add" style="color: #006e28">
<p><code class="sourceCode default">#define __cpp_lib_optional_construct_or yyyymmL // also in &lt;optional&gt;</code></p>
</div>
</blockquote>
<h2 data-number="8.2" id="changes-to-optional"><span class="header-section-number">8.2</span> Changes to
<code class="sourceCode default">optional</code><a href="#changes-to-optional" class="self-link"></a></h2>
<p>In <span>22.5.3.1
<a href="https://wg21.link/N4971#optional.optional.general">[optional.optional.general]</a></span>
<em>in the Working Draft</em>, insert the
<code class="sourceCode default">or_construct</code> observer after
<code class="sourceCode default">value_or</code>:</p>
<blockquote>
<div class="line-block"><code class="sourceCode default">template&lt;class U&gt; constexpr T value_or(U&amp;&amp;) const &amp;;</code><br />
<code class="sourceCode default">template&lt;class U&gt; constexpr T value_or(U&amp;&amp;) &amp;&amp;;</code></div>
<div class="add" style="color: #006e28">

<div class="line-block"><code class="sourceCode default">template &lt;class U = remove_cvref_t&lt;T&gt;, class... Args&gt;</code><br />
    <code class="sourceCode default">U constexpr or_construct(Args&amp;&amp;...);</code><br />
<code class="sourceCode default">template &lt;class U = remove_cvref_t&lt;T&gt;, class... Args&gt;</code><br />
    <code class="sourceCode default">U constexpr or_construct(Args&amp;&amp;...) const;</code><br />
<code class="sourceCode default">template &lt;class U = remove_cvref_t&lt;T&gt;, class X, class... Args&gt;</code><br />
    <code class="sourceCode default">U constexpr or_construct(initializer_list&lt;X&gt;, Args&amp;&amp;...);</code><br />
<code class="sourceCode default">template &lt;class U = remove_cvref_t&lt;T&gt;, class X, class... Args&gt;</code><br />
    <code class="sourceCode default">U constexpr or_construct(initializer_list&lt;X&gt;, Args&amp;&amp;...) const;</code></div>

</div>
</blockquote>
<p>In the <code class="sourceCode default">optional&lt;T&amp;&gt;</code>
wording <em>in <span class="citation" data-cites="P2988R3">[<a href="#ref-P2988R3" role="doc-biblioref">P2988R3</a>]</span></em>,
change <code class="sourceCode default">value_or</code> and add
<code class="sourceCode default">or_construct</code> to
[optional.optional.general]:</p>
<blockquote>
<div class="line-block"><code class="sourceCode default">template&lt;class U&gt; constexpr</code>
<span class="rm" style="color: #bf0303"><del><span><code class="sourceCode default">T&amp;</code></span></del></span>
<span class="add" style="color: #006e28"><ins><em>see
below</em></ins></span>
<code class="sourceCode default">value_or(U&amp;&amp;) const;</code></div>
<div class="add" style="color: #006e28">

<div class="line-block"><code class="sourceCode default">template &lt;class U = remove_cv_t&lt;T&gt;, class... Args&gt;</code><br />
    <code class="sourceCode default">U or_construct(Args&amp;&amp;...) const;</code><br />
<code class="sourceCode default">template &lt;class U = remove_cv_t&lt;T&gt;, class X, class... Args&gt;</code><br />
    <code class="sourceCode default">U constexpr or_construct(initializer_list&lt;X&gt;, Args&amp;&amp;...) const;</code></div>

</div>
</blockquote>
<p>At the end of <span>22.5.3.6
<a href="https://wg21.link/N4971#optional.observe">[optional.observe]</a></span>
<em>in the Working Draft</em>, add the definition of
<code class="sourceCode default">or_construct</code>:</p>
<div class="add" style="color: #006e28">

<blockquote>
<div class="line-block"><code class="sourceCode default">template &lt;class U = remove_cvref_t&lt;T&gt;, class... Args&gt;</code><br />
    <code class="sourceCode default">U or_construct(Args&amp;&amp;... args);</code><br />
<code class="sourceCode default">template &lt;class U = remove_cvref_t&lt;T&gt;, class... Args&gt;</code><br />
    <code class="sourceCode default">U or_construct(Args&amp;&amp;... args) const;</code></div>
</blockquote>
<blockquote>
<blockquote>
<p><em>Mandates</em>: <code class="sourceCode default">is_constructible_v&lt;U, decltype(**this)&gt; &amp;&amp;</code>
<code class="sourceCode default">is_constructible_v&lt;U, Args...&gt;</code><br />
is <code class="sourceCode default">true</code>. If
<code class="sourceCode default">U</code> is an lvalue reference type,
then <code class="sourceCode default">sizeof...(Args)</code> is
<code class="sourceCode default">1</code> and, for
<code class="sourceCode default">A0</code> being<br />
the single type in <code class="sourceCode default">Args</code>, <code class="sourceCode default">is_lvalue_reference_v&lt;A0&gt; &amp;&amp;</code><br />
<code class="sourceCode default">is_convertible_v&lt;add_pointer_t&lt;A0&gt;, add_pointer_t&lt;U&gt;&gt; &amp;&amp;</code><br />
<code class="sourceCode default">is_convertible_v&lt;add_pointer_t&lt;T&gt;, add_pointer_t&lt;U&gt;&gt;</code>
is <code class="sourceCode default">true</code>.</p>
</blockquote>
</blockquote>
<blockquote>
<blockquote>
<p><em>Effects</em>: Equivalent to:</p>
</blockquote>
</blockquote>
<blockquote>
<blockquote>
<blockquote>
<p><code class="sourceCode default">return has_value() ? U(**this) : U(std::forward&lt;Args&gt;(args)...);</code></p>
</blockquote>
</blockquote>
</blockquote>
<blockquote>
<div class="line-block"><code class="sourceCode default">template &lt;class U = remove_cvref_t&lt;T&gt;, class X, class... Args&gt;</code><br />
    <code class="sourceCode default">U constexpr or_construct(initializer_list&lt;X&gt; il, Args&amp;&amp;...);</code><br />
<code class="sourceCode default">template &lt;class U = remove_cvref_t&lt;T&gt;, class X, class... Args&gt;</code><br />
    <code class="sourceCode default">U constexpr or_construct(initializer_list&lt;X&gt; il, Args&amp;&amp;...) const;</code></div>
</blockquote>
<blockquote>
<blockquote>
<p><em>Mandates</em>: <code class="sourceCode default">! is_reference_v&lt;U&gt; &amp;&amp;</code>
<code class="sourceCode default">is_constructible_v&lt;U, initializer_list&lt;X&gt;, Args...&gt; &amp;&amp;</code><br />
<code class="sourceCode default">is_constructible_v&lt;U, decltype(**this)&gt;</code>
is <code class="sourceCode default">true</code>.</p>
</blockquote>
</blockquote>
<blockquote>
<blockquote>
<p><em>Effects</em>: Equivalent to:</p>
</blockquote>
</blockquote>
<blockquote>
<blockquote>
<blockquote>
<p><code class="sourceCode default">return has_value() ? U(**this) : U(il, std::forward&lt;Args&gt;(args)...);</code></p>
</blockquote>
</blockquote>
</blockquote>

</div>
<p>In the <code class="sourceCode default">optional&lt;T&amp;&gt;</code>
wording <em>in <span class="citation" data-cites="P2988R3">[<a href="#ref-P2988R3" role="doc-biblioref">P2988R3</a>]</span></em>,
change the definition of
<code class="sourceCode default">value_or</code> and add the definition
of <code class="sourceCode default">or_construct</code> to
[optional.observe] :</p>
<blockquote>
<div class="line-block"><code class="sourceCode default">template&lt;class U&gt; constexpr</code>
<span class="rm" style="color: #bf0303"><del><span><code class="sourceCode default">T&amp;</code></span></del></span>
<span class="add" style="color: #006e28"><ins><em>see
below</em></ins></span>
<code class="sourceCode default">value_or(U&amp;&amp; v) const;</code></div>
</blockquote>
<blockquote>
<blockquote>
<p><span class="add" style="color: #006e28"><ins>The return type is
<span><code class="sourceCode default">common_reference_t&lt;T&amp;&gt;, U&gt;</code></span>
Let <em>R</em> designate the return type.</ins></span></p>
</blockquote>
</blockquote>
<blockquote>
<blockquote>
<p><em>Mandates</em>: <span class="rm" style="color: #bf0303"><del><span><code class="sourceCode default">is_constructible_v&lt;T&amp;, U&gt;</code></span>
is
<span><code class="sourceCode default">true</code></span></del></span>
<span class="add" style="color: #006e28"><ins><em>R</em> is well formed
and is an lvalue reference type. <span><code class="sourceCode default">reference_constructs_from_temporary_v&lt;<em>R</em>, U&gt; &amp;&amp;</code></span><br />
<span><code class="sourceCode default">is_convertible_v&lt;add_pointer_t&lt;T&gt;, add_pointer_t&lt;<em>R</em>&gt;&gt; &amp;&amp;</code></span><br />
<span><code class="sourceCode default">is_convertible_v&lt;add_pointer_t&lt;U&gt;, add_pointer_t&lt;<em>R</em>&gt;&gt;</code></span>
is
<span><code class="sourceCode default">true</code></span></ins></span>.</p>
</blockquote>
</blockquote>
<blockquote>
<blockquote>
<p><em>Effects</em>: Equivalent to:</p>
</blockquote>
</blockquote>
<blockquote>
<blockquote>
<blockquote>
<p><code class="sourceCode default">return has_value() ?</code> <span class="add" style="color: #006e28"><ins><span><code class="sourceCode default">static_cast&lt;<em>R</em>&gt;(</code></span></ins></span><code class="sourceCode default">value()</code><span class="add" style="color: #006e28"><ins><span><code class="sourceCode default">)</code></span></ins></span>
<code class="sourceCode default">:</code> <span class="add" style="color: #006e28"><ins><span><code class="sourceCode default">static_cast&lt;<em>R</em>&gt;(</code></span></ins></span><code class="sourceCode default">forward&lt;U&gt;(u)</code><span class="add" style="color: #006e28"><ins><span><code class="sourceCode default">)</code></span></ins></span><code class="sourceCode default">;</code></p>
</blockquote>
</blockquote>
</blockquote>
<div class="add" style="color: #006e28">

<blockquote>
<blockquote>
<p><em>Remark</em>: This function participates in overload resolution
even when the return type is ill-formed; if selected, the program is
ill-formed.</p>
</blockquote>
</blockquote>

</div>
<div class="add" style="color: #006e28">

<blockquote>
<div class="line-block"><code class="sourceCode default">template &lt;class U = T, class... Args&gt;</code><br />
    <code class="sourceCode default">U or_construct(Args&amp;&amp;...args) const;</code></div>
</blockquote>
<blockquote>
<blockquote>
<p><em>Mandates</em>: <code class="sourceCode default">is_constructible_v&lt;U, decltype(**this)&gt; &amp;&amp;</code>
<code class="sourceCode default">is_constructible_v&lt;U, Args...&gt;</code><br />
is <code class="sourceCode default">true</code>. If
<code class="sourceCode default">U</code> is an lvalue reference type,
then <code class="sourceCode default">sizeof...(Args)</code> is
<code class="sourceCode default">1</code> and, for
<code class="sourceCode default">A0</code> being<br />
the single type in <code class="sourceCode default">Args</code>, <code class="sourceCode default">is_lvalue_reference_v&lt;A0&gt; &amp;&amp;</code><br />
<code class="sourceCode default">is_convertible_v&lt;add_pointer_t&lt;A0&gt;, add_pointer_t&lt;U&gt;&gt; &amp;&amp;</code><br />
<code class="sourceCode default">is_convertible_v&lt;add_pointer_t&lt;T&gt;, add_pointer_t&lt;U&gt;&gt;</code>
is <code class="sourceCode default">true</code>.</p>
</blockquote>
</blockquote>
<blockquote>
<blockquote>
<p><em>Effects</em>: Equivalent to:</p>
</blockquote>
</blockquote>
<blockquote>
<blockquote>
<blockquote>
<p><code class="sourceCode default">return has_value() ? U(**this) : U(std::forward&lt;Args&gt;(args)...);</code></p>
</blockquote>
</blockquote>
</blockquote>
<blockquote>
<div class="line-block"><code class="sourceCode default">template &lt;class U = remove_cv_t&lt;T&gt;, class X, class... Args&gt;</code><br />
    <code class="sourceCode default">U constexpr or_construct(initializer_list&lt;X&gt; il, Args&amp;&amp;...) const;</code></div>
</blockquote>
<blockquote>
<blockquote>
<p><em>Mandates</em>: <code class="sourceCode default">! is_reference_v&lt;U&gt; &amp;&amp;</code>
<code class="sourceCode default">is_constructible_v&lt;U, initializer_list&lt;X&gt;, Args...&gt; &amp;&amp;</code><br />
<code class="sourceCode default">is_constructible_v&lt;U, decltype(**this)&gt;</code>
is <code class="sourceCode default">true</code>.</p>
</blockquote>
</blockquote>
<blockquote>
<blockquote>
<p><em>Effects</em>: Equivalent to:</p>
</blockquote>
</blockquote>
<blockquote>
<blockquote>
<blockquote>
<p><code class="sourceCode default">return has_value() ? U(**this) : U(il, std::forward&lt;Args&gt;(args)...);</code></p>
</blockquote>
</blockquote>
</blockquote>

</div>
<h2 data-number="8.3" id="changes-to-map-and-unordered_map"><span class="header-section-number">8.3</span> Changes to
<code class="sourceCode default">map</code> and
<code class="sourceCode default">unordered_map</code><a href="#changes-to-map-and-unordered_map" class="self-link"></a></h2>
<p>In <span>24.4.4.1
<a href="https://wg21.link/N4971#map.overview">[map.overview]</a></span>/2,
insert the <code class="sourceCode default">get</code> element-access
members:</p>
<blockquote>
<div class="line-block"><code class="sourceCode default">//</code>
<em><span>24.4.4.3
<a href="https://wg21.link/N4971#map.access">[map.access]</a></span>,
element access</em><br />
<code class="sourceCode default">mapped_type&amp; operator[](const key_type&amp; x);</code><br />
<code class="sourceCode default">mapped_type&amp; operator[](key_type&amp;&amp; x);</code><br />
<code class="sourceCode default">template&lt;class K&gt; mapped_type&amp; operator[](K&amp;&amp; x);</code><br />
<code class="sourceCode default">mapped_type&amp;       at(const key_type&amp; x);</code><br />
<code class="sourceCode default">const mapped_type&amp; at(const key_type&amp; x) const;</code><br />
<code class="sourceCode default">template&lt;class K&gt; mapped_type&amp;       at(const K&amp; x);</code><br />
<code class="sourceCode default">template&lt;class K&gt; const mapped_type&amp; at(const K&amp; x) const;</code></div>
<div class="add" style="color: #006e28">

<div class="line-block"><code class="sourceCode default">optional&lt;mapped_type&amp;&gt;       get(const key_type&amp; x) noexcept;</code><br />
<code class="sourceCode default">optional&lt;const mapped_type&amp;&gt; get(const key_type&amp; x) const noexcept;</code><br />
<code class="sourceCode default">template&lt;class K&gt; optional&lt;mapped_type&amp;&gt;       get(const K&amp; x) noexcept;</code><br />
<code class="sourceCode default">template&lt;class K&gt; optional&lt;const mapped_type&amp;&gt; get(const K&amp; x) const noexcept;</code></div>

</div>
</blockquote>
<p>At the end of <span>24.4.4.3
<a href="https://wg21.link/N4971#map.access">[map.access]</a></span>,
add these descriptions:</p>
<div class="add" style="color: #006e28">

<blockquote>
<div class="line-block"><code class="sourceCode default">optional&lt;mapped_type&amp;&gt;       get(const key_type&amp; x) noexcept;</code><br />
<code class="sourceCode default">optional&lt;const mapped_type&amp;&gt; get(const key_type&amp; x) const noexcept;</code><br />
<code class="sourceCode default">template&lt;class K&gt; optional&lt;mapped_type&amp;&gt;       get(const K&amp; x) noexcept;</code><br />
<code class="sourceCode default">template&lt;class K&gt; optional&lt;const mapped_type&amp;&gt; get(const K&amp; x) const noexcept;</code></div>
</blockquote>
<blockquote>
<blockquote>
<p><em>Constraints</em>: For the third and fourth overloads, the
<em>qualified-id</em>
<code class="sourceCode default">Compare::is_transparent</code> is valid
and denotes a type.</p>
</blockquote>
</blockquote>
<blockquote>
<blockquote>
<p><em>Preconditions</em>: The expression
<code class="sourceCode default">find(x)</code> is well formed and has
well-defined behavior.</p>
</blockquote>
</blockquote>
<blockquote>
<blockquote>
<p><em>Returns</em>:
<code class="sourceCode default">find(x)-&gt;second</code> if
<code class="sourceCode default">find(x) == end()</code> is
<code class="sourceCode default">false</code>, otherwise
<code class="sourceCode default">nullopt</code>.</p>
</blockquote>
</blockquote>
<blockquote>
<blockquote>
<p><em>Complexity</em>: Logarithmic</p>
</blockquote>
</blockquote>

</div>
<p>In <span>24.5.4.1
<a href="https://wg21.link/N4971#unord.map.overview">[unord.map.overview]</a></span>/3,
insert the <code class="sourceCode default">get</code> element-access
members:</p>
<blockquote>
<div class="line-block"><code class="sourceCode default">//</code>
<em><span>24.5.4.3
<a href="https://wg21.link/N4971#unord.map.elem">[unord.map.elem]</a></span>,
element access</em><br />
<code class="sourceCode default">mapped_type&amp; operator[](const key_type&amp; x);</code><br />
<code class="sourceCode default">mapped_type&amp; operator[](key_type&amp;&amp; x);</code><br />
<code class="sourceCode default">template&lt;class K&gt; mapped_type&amp; operator[](K&amp;&amp; x);</code><br />
<code class="sourceCode default">mapped_type&amp;       at(const key_type&amp; x);</code><br />
<code class="sourceCode default">const mapped_type&amp; at(const key_type&amp; x) const;</code><br />
<code class="sourceCode default">template&lt;class K&gt; mapped_type&amp;       at(const K&amp; x);</code><br />
<code class="sourceCode default">template&lt;class K&gt; const mapped_type&amp; at(const K&amp; x) const;</code></div>
<div class="add" style="color: #006e28">

<div class="line-block"><code class="sourceCode default">optional&lt;mapped_type&amp;&gt;       get(const key_type&amp; x) noexcept;</code><br />
<code class="sourceCode default">optional&lt;const mapped_type&amp;&gt; get(const key_type&amp; x) const noexcept;</code><br />
<code class="sourceCode default">template&lt;class K&gt; optional&lt;mapped_type&amp;&gt;       get(const K&amp; x) noexcept;</code><br />
<code class="sourceCode default">template&lt;class K&gt; optional&lt;const mapped_type&amp;&gt; get(const K&amp; x) const noexcept;</code></div>

</div>
</blockquote>
<p>At the end of <span>24.5.4.3
<a href="https://wg21.link/N4971#unord.map.elem">[unord.map.elem]</a></span>,
add these descriptions:</p>
<div class="add" style="color: #006e28">

<blockquote>
<div class="line-block"><code class="sourceCode default">optional&lt;mapped_type&amp;&gt;       get(const key_type&amp; x) noexcept;</code><br />
<code class="sourceCode default">optional&lt;const mapped_type&amp;&gt; get(const key_type&amp; x) const noexcept;</code><br />
<code class="sourceCode default">template&lt;class K&gt; optional&lt;mapped_type&amp;&gt;       get(const K&amp; x) noexcept;</code><br />
<code class="sourceCode default">template&lt;class K&gt; optional&lt;const mapped_type&amp;&gt; get(const K&amp; x) const noexcept;</code></div>
</blockquote>
<blockquote>
<blockquote>
<p><em>Constraints</em>: For the third and fourth overloads, the
<em>qualified-id</em>s
<code class="sourceCode default">Hash::is_transparent</code> and
<code class="sourceCode default">Pred::is_transparent</code> are valid
and denote types.</p>
</blockquote>
</blockquote>
<blockquote>
<blockquote>
<p><em>Preconditions</em>: The expression
<code class="sourceCode default">find(x)</code> is well formed and has
well-defined behavior.</p>
</blockquote>
</blockquote>
<blockquote>
<blockquote>
<p><em>Returns</em>:
<code class="sourceCode default">find(x)-&gt;second</code> if
<code class="sourceCode default">find(x) == end()</code> is
<code class="sourceCode default">false</code>, otherwise
<code class="sourceCode default">nullopt</code>.</p>
</blockquote>
</blockquote>

</div>
<h1 data-number="9" id="acknowledgments"><span class="header-section-number">9</span> Acknowledgments<a href="#acknowledgments" class="self-link"></a></h1>
<p>Thanks to Tomasz Kamiński for pushing me on the
<code class="sourceCode default">optional&lt;T&amp;&gt;</code>
approach.</p>
<p>Thanks to Lori Hughes for editing support.</p>
<h1 data-number="10" id="bibliography"><span class="header-section-number">10</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-Folly" class="csl-entry" role="doc-biblioentry">
[Folly] Meta. folly/folly/MapUtil.h. <a href="https://github.com/facebook/folly/blob/323e467e2375e535e10bda62faf2569e8f5c9b19/folly/MapUtil.h#L35-L71"><div class="csl-block">https://github.com/facebook/folly/blob/323e467e2375e535e10bda62faf2569e8f5c9b19/folly/MapUtil.h#L35-L71</div></a>
</div>
<div id="ref-N4971" class="csl-entry" role="doc-biblioentry">
[N4971] Thomas Köppe. 2023-12-18. Working Draft, Programming Languages —
C++. <a href="https://wg21.link/n4971"><div class="csl-block">https://wg21.link/n4971</div></a>
</div>
<div id="ref-P0429R9" class="csl-entry" role="doc-biblioentry">
[P0429R9] Zach Laine. 2022-06-17. A Standard flat_map. <a href="https://wg21.link/p0429r9"><div class="csl-block">https://wg21.link/p0429r9</div></a>
</div>
<div id="ref-P2767R2" class="csl-entry" role="doc-biblioentry">
[P2767R2] Arthur O’Dwyer. 2023-12-09. flat_map/flat_set omnibus. <a href="https://wg21.link/p2767r2"><div class="csl-block">https://wg21.link/p2767r2</div></a>
</div>
<div id="ref-P2988R3" class="csl-entry" role="doc-biblioentry">
[P2988R3] Steve Downey, Peter Sommerlad. 2024-02-15.
std::optional&lt;T&amp;&gt;. <a href="https://wg21.link/p2988r3"><div class="csl-block">https://wg21.link/p2988r3</div></a>
</div>
<div id="ref-P3091R0" class="csl-entry" role="doc-biblioentry">
[P3091R0] Pablo Halpern. 2024-02-06. Better lookups for `map` and
`unordered_map`. <a href="https://wg21.link/p3091r0"><div class="csl-block">https://wg21.link/p3091r0</div></a>
</div>
</div>
<section class="footnotes footnotes-end-of-document" role="doc-endnotes">
<hr />
<ol>
<li id="fn1" role="doc-endnote"><p>All citations to the Standard are to
working draft N4971 unless otherwise specified.<a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>
</div>
</div>
</body>
</html>
