<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang xml:lang>

<head>
    <meta charset="utf-8" />
    <meta name="generator" content="mpark/wg21" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />      <meta name="dcterms.date" content="2019-10-06" />      <title>function_ref: a non-owning reference to a Callable</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%;
        }
        
        
    </style>
        <style>
        code.sourceCode > span { display: inline-block; line-height: 1.25; }
        code.sourceCode > span { color: inherit; text-decoration: inherit; }
        code.sourceCode > span:empty { height: 1.2em; }
        .sourceCode { overflow: visible; }
        code.sourceCode { white-space: pre; position: relative; }
        div.sourceCode { margin: 1em 0; }
        pre.sourceCode { margin: 0; }
        @media screen {
        div.sourceCode { overflow: auto; }
        }
        @media print {
        code.sourceCode { white-space: pre-wrap; }
        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 {
        code.sourceCode > span > a:first-child::before { text-decoration: underline; }
        }
        code span. { } /* Normal */
        code span.al { color: #ff0000; } /* Alert */
        code span.an { } /* Annotation */
        code span.at { } /* Attribute */
        code span.bn { color: #9f6807; } /* BaseN */
        code span.bu { color: #9f6807; } /* BuiltIn */
        code span.cf { color: #00607c; } /* ControlFlow */
        code span.ch { color: #9f6807; } /* Char */
        code span.cn { } /* Constant */
        code span.co { color: #008000; font-style: italic; } /* Comment */
        code span.cv { color: #008000; font-style: italic; } /* CommentVar */
        code span.do { color: #008000; } /* Documentation */
        code span.dt { color: #00607c; } /* DataType */
        code span.dv { color: #9f6807; } /* DecVal */
        code span.er { color: #ff0000; font-weight: bold; } /* Error */
        code span.ex { } /* Extension */
        code span.fl { color: #9f6807; } /* Float */
        code span.fu { } /* Function */
        code span.im { } /* Import */
        code span.in { color: #008000; } /* Information */
        code span.kw { color: #00607c; } /* Keyword */
        code span.op { color: #af1915; } /* Operator */
        code span.ot { } /* Other */
        code span.pp { color: #6f4e37; } /* Preprocessor */
        code span.re { } /* RegionMarker */
        code span.sc { color: #9f6807; } /* SpecialChar */
        code span.ss { color: #9f6807; } /* SpecialString */
        code span.st { color: #9f6807; } /* String */
        code span.va { } /* Variable */
        code span.vs { color: #9f6807; } /* VerbatimString */
        code span.wa { color: #008000; font-weight: bold; } /* Warning */ code.diff {
            color: #898887
        }
        
        code.diff span.va {
            color: #006e28
        }
        
        code.diff span.st {
            color: #bf0303
        }
    </style>
         <style type="text/css">
body {
margin: 5em;
font-family: serif;

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

a.index:target {
display: inline;
}
.indexitems {
margin-left: 2em;
text-indent: -2em;
}
div.itemdescr {
margin-left: 3em;
}
.bnf {
font-family: serif;
margin-left: 40pt;
margin-top: 0.5em;
margin-bottom: 0.5em;
}
.ncbnf {
font-family: serif;
margin-top: 0.5em;
margin-bottom: 0.5em;
margin-left: 40pt;
}
.ncsimplebnf {
font-family: serif;
font-style: italic;
margin-top: 0.5em;
margin-bottom: 0.5em;
margin-left: 40pt;
background: inherit;

}
span.textnormal {
font-style: normal;
font-family: serif;
white-space: normal;
display: inline-block;
}
span.rlap {
display: inline-block;
width: 0px;
}
span.descr {
font-style: normal;
font-family: serif;
}
span.grammarterm {
font-style: italic;
}
span.term {
font-style: italic;
}
span.terminal {
font-family: monospace;
font-style: normal;
}
span.nonterminal {
font-style: italic;
}
span.tcode {
font-family: monospace;
font-style: normal;
}
span.textbf {
font-weight: bold;
}
span.textsc {
font-variant: small-caps;
}
a.nontermdef {
font-style: italic;
font-family: serif;
}
span.emph {
font-style: italic;
}
span.techterm {
font-style: italic;
}
span.mathit {
font-style: italic;
}
span.mathsf {
font-family: sans-serif;
}
span.mathrm {
font-family: serif;
font-style: normal;
}
span.textrm {
font-family: serif;
}
span.textsl {
font-style: italic;
}
span.mathtt {
font-family: monospace;
font-style: normal;
}
span.mbox {
font-family: serif;
font-style: normal;
}
span.ungap {
display: inline-block;
width: 2pt;
}
span.textit {
font-style: italic;
}
span.texttt {
font-family: monospace;
}
span.tcode_in_codeblock {
font-family: monospace;
font-style: normal;
}
span.phantom {
color: white;
}

span.math {
font-style: normal;
}
span.mathblock {
display: block;
margin-left: auto;
margin-right: auto;
margin-top: 1.2em;
margin-bottom: 1.2em;
text-align: center;
}
span.mathalpha {
font-style: italic;
}
span.synopsis {
font-weight: bold;
margin-top: 0.5em;
display: block;
}
span.definition {
font-weight: bold;
display: block;
}
.codeblock {
margin-left: 1.2em;
line-height: 127%;
}
.outputblock {
margin-left: 1.2em;
line-height: 127%;
}
div.itemdecl {
margin-top: 2ex;
}
code.itemdeclcode {
white-space: pre;
display: block;
}
span.textsuperscript {
vertical-align: super;
font-size: smaller;
line-height: 0;
}
.footnotenum {
vertical-align: super;
font-size: smaller;
line-height: 0;
}
.footnote {
font-size: small;
margin-left: 2em;
margin-right: 2em;
margin-top: 0.6em;
margin-bottom: 0.6em;
}
div.minipage {
display: inline-block;
margin-right: 3em;
}
div.numberedTable {
text-align: center;
margin: 2em;
}
div.figure {
text-align: center;
margin: 2em;
}
table {
border: 1px solid black;
border-collapse: collapse;
margin-left: auto;
margin-right: auto;
margin-top: 0.8em;
text-align: left;
hyphens: none;

}
td,
th {
padding-left: 1em;
padding-right: 1em;
vertical-align: top;
}
td.empty {
padding: 0px;
padding-left: 1px;
}
td.left {
text-align: left;
}
td.right {
text-align: right;
}
td.center {
text-align: center;
}
td.justify {
text-align: justify;
}
td.border {
border-left: 1px solid black;
}
tr.rowsep,
td.cline {
border-top: 1px solid black;
}
tr.even,
tr.odd {
border-bottom: 1px solid black;
}
tr.capsep {
border-top: 3px solid black;
border-top-style: double;
}
tr.header {
border-bottom: 3px solid black;
border-bottom-style: double;
}
th {
border-bottom: 1px solid black;
}
span.centry {
font-weight: bold;
}
div.table {
display: block;
margin-left: auto;
margin-right: auto;
text-align: center;
width: 90%;
}
span.indented {
display: block;
margin-left: 2em;
margin-bottom: 1em;
margin-top: 1em;
}
ol.enumeratea {
list-style-type: none;
background: inherit;
}
ol.enumerate {
list-style-type: none;
background: inherit;
}

code.sourceCode>span {
display: inline;
}

div#refs p {
padding-left: 32px;
text-indent: -32px;
}
pre.sourceCode {
border: 1px solid #444;
padding: 12px;
border-radius: 6px
}
html {
font-size: 100%;
overflow-y: scroll;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%
}
body {
color: #444;
font-family: georgia, palatino, palatino linotype, times, times new roman, serif;
font-size: 12px;
line-height: 1.7;
padding: 1em;
margin: auto;
max-width: 54em;
background: #fefefe
}
a {
color: #0645ad;
text-decoration: none
}
a:visited {
color: #0b0080
}
a:hover {
color: #06e
}
a:active {
color: #faa700
}
a:focus {
outline: thin dotted
}
*::-moz-selection {
background: rgba(255, 255, 0, .3);
color: #000
}
*::selection {
background: rgba(255, 255, 0, .3);
color: #000
}
a::-moz-selection {
background: rgba(255, 255, 0, .3);
color: #0645ad
}
a::selection {
background: rgba(255, 255, 0, .3);
color: #0645ad
}
p {
margin: 1em 0
}
img {
max-width: 100%
}
h1,
h2,
h3,
h4,
h5,
h6 {
color: #111;
line-height: 125%;
margin-top: 2em;
font-weight: 400
}
h4,
h5,
h6 {
font-weight: 700
}
h1 {
font-size: 2.5em
}
h2 {
font-size: 2em
}
h3 {
font-size: 1.5em
}
h4 {
font-size: 1.2em
}
h5 {
font-size: 1em
}
h6 {
font-size: .9em
}
blockquote {
color: #666;
margin: 0;
padding-left: 3em;
border-left: .5em #eee solid
}
hr {
display: block;
height: 2px;
border: 0;
border-top: 1px solid #aaa;
border-bottom: 1px solid #eee;
margin: 1em 0;
padding: 0
}
pre,
code,
kbd,
samp {
color: #000;
font-family: monospace, monospace;
_font-family: 'courier new', monospace;
font-size: .98em
}
pre {
white-space: pre;
white-space: pre-wrap;
word-wrap: break-word
}
b,
strong {
font-weight: 700
}
dfn {
font-style: italic
}
ins {
background: #ff9;
color: #000;
text-decoration: none
}
mark {
background: #ff0;
color: #000;
font-style: italic;
font-weight: 700
}
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline
}
sup {
top: -.5em
}
sub {
bottom: -.25em
}
ul,
ol {
margin: 1em 0;
padding: 0 0 0 2em
}
li p:last-child {
margin-bottom: 0
}
ul ul,
ol ol {
margin: .3em 0
}
dl {
margin-bottom: 1em
}
dt {
font-weight: 700;
margin-bottom: .8em
}
dd {
margin: 0 0 .8em 2em
}
dd:last-child {
margin-bottom: 0
}
img {
border: 0;
-ms-interpolation-mode: bicubic;
vertical-align: middle
}
figure {
display: block;
text-align: center;
margin: 1em 0
}
figure img {
border: 0;
margin: 0 auto
}
figcaption {
font-size: .8em;
font-style: italic;
margin: 0 0 .8em
}
table {
margin-bottom: 2em;
border-bottom: 1px solid #ddd;
border-right: 1px solid #ddd;
border-spacing: 0;
border-collapse: collapse
}
table th {
padding: .2em 1em;
background-color: #eee;
border-top: 1px solid #ddd;
border-left: 1px solid #ddd
}
table td {
padding: .2em 1em;
border-top: 1px solid #ddd;
border-left: 1px solid #ddd;
vertical-align: top
}
.author {
font-size: 1.2em;
text-align: center
}
@media only screen and (min-width:480px) {
body {
font-size: 14px
}
}
@media only screen and (min-width:768px) {
body {
font-size: 16px
}
}
@media print {
* {
background: transparent!important;
color: #000!important;
filter: none!important;
-ms-filter: none!important
}
body {
font-size: 12pt;
max-width: 100%
}
a,
a:visited {
text-decoration: underline
}
hr {
height: 1px;
border: 0;
border-bottom: 1px solid #000
}
a[href]:after {
content: " (" attr(href) ")"
}
abbr[title]:after {
content: " (" attr(title) ")"
}
.ir a:after,
a[href^="javascript:"]:after,
a[href^="#"]:after {
content: ""
}
pre,
blockquote {
border: 1px solid #999;
padding-right: 1em;
page-break-inside: avoid
}
tr,
img {
page-break-inside: avoid
}
img {
max-width: 100%!important
}
@page: left {
margin: 15mm 20mm 15mm 10mm
}
@page: right {
margin: 15mm 10mm 15mm 20mm
}
p,
h2,
h3 {
orphans: 3;
widows: 3
}
h2,
h3 {
page-break-after: avoid
}
}
@media only screen and (min-width: 1200px) and (max-width: 1680px) {
.sidebar ul {
columns: 2;
font-size: smaller;
}
}
@media only screen and (min-width: 1680px) {
.sidebar {
float: left;
position: fixed;
top: -20px;
left: 0px;
background-color: aliceblue;
line-height: 1.3;
padding-right: 20px;
zoom: 90%;
max-width: 360px;
height: 100%;
overflow-y: scroll;
}
.sidebartitle {
margin-top: 30px;
padding-left: 20px;
margin-bottom: 10px;
color: darkslateblue;
}
.sidebar ul {
columns: 1;
}
}
@media only screen and (min-width: 2000px) {
body {
max-width: 70em;
}
body .wrapper {
max-width: 70em;
}
}</style>     <!-- <link rel="icon" href="https://isocpp.org/favicon.ico" /> -->
    
    <!--[if lt IE 9]>
    <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
  <![endif]-->
      
</head>

<body>
    <div class="wrapper">
                 <header id="title-block-header">
            <h1 class="title" style="text-align:center"><code>function_ref</code>: a non-owning reference to a <code>Callable</code></h1>
            
            <table style="float:right">
                <tr>
                    <td>Document #: </td>
                    <td>P0792R5</td>
                </tr>
                <tr>
                    <td>Date: </td>
                    <td>2019-10-06</td>
                </tr>
                <tr>
                    <td style="vertical-align:top">Project: </td>
                    <td>Programming Language C++<br>  Library Working Group (LWG)
                        <br> 
                    </td>
                </tr>
                                <tr>
                    <td style="vertical-align:top">Reply-to: </td>
                    <td>
                         Vittorio Romeo
                        <br>
                        &lt;<a href="mailto:vittorio.romeo@outlook.com" class="email">vittorio.romeo@outlook.com</a>&gt;<br> 
                    </td>
                </tr>
            </table>

        </header>
                <div style="clear:both">
                        <div id="TOC" role="doc-toc" class="sidebar">
                <h1 id="toctitle" class="sidebartitle">Contents</h1>
                <ul>
                <li><a href="#abstract"><span class="toc-section-number">1</span> Abstract<span></span></a></li>
                <li><a href="#changelog-and-polls"><span class="toc-section-number">2</span> Changelog and polls<span></span></a><ul>
                <li><a href="#r5"><span class="toc-section-number">2.1</span> R5<span></span></a></li>
                <li><a href="#r4"><span class="toc-section-number">2.2</span> R4<span></span></a></li>
                <li><a href="#r3"><span class="toc-section-number">2.3</span> R3<span></span></a><ul>
                <li><a href="#polls"><span class="toc-section-number">2.3.1</span> Polls<span></span></a></li>
                </ul></li>
                <li><a href="#r2"><span class="toc-section-number">2.4</span> R2<span></span></a><ul>
                <li><a href="#polls-1"><span class="toc-section-number">2.4.1</span> Polls<span></span></a></li>
                </ul></li>
                <li><a href="#r1"><span class="toc-section-number">2.5</span> R1<span></span></a><ul>
                <li><a href="#polls-2"><span class="toc-section-number">2.5.1</span> Polls<span></span></a></li>
                </ul></li>
                </ul></li>
                <li><a href="#overview"><span class="toc-section-number">3</span> Overview<span></span></a></li>
                <li><a href="#motivating-example"><span class="toc-section-number">4</span> Motivating example<span></span></a></li>
                <li><a href="#impact-on-the-standard"><span class="toc-section-number">5</span> Impact on the Standard<span></span></a></li>
                <li><a href="#alternatives"><span class="toc-section-number">6</span> Alternatives<span></span></a></li>
                <li><a href="#changes-to-functional-header"><span class="toc-section-number">7</span> Changes to <code>&lt;functional&gt;</code> header<span></span></a></li>
                <li><a href="#class-synopsis"><span class="toc-section-number">8</span> Class synopsis<span></span></a></li>
                <li><a href="#specification"><span class="toc-section-number">9</span> Specification<span></span></a></li>
                <li><a href="#feature-test-macro"><span class="toc-section-number">10</span> Feature test macro<span></span></a></li>
                <li><a href="#example-implementation"><span class="toc-section-number">11</span> Example implementation<span></span></a></li>
                <li><a href="#existing-practice"><span class="toc-section-number">12</span> Existing practice<span></span></a></li>
                <li><a href="#possible-issues"><span class="toc-section-number">13</span> Possible issues<span></span></a></li>
                <li><a href="#bikeshedding"><span class="toc-section-number">14</span> Bikeshedding<span></span></a></li>
                <li><a href="#acknowledgments"><span class="toc-section-number">15</span> Acknowledgments<span></span></a></li>
                <li><a href="#annex-previously-open-questions"><span class="toc-section-number">16</span> Annex: previously open questions<span></span></a></li>
                <li><a href="#annex-controversial-design-decisions"><span class="toc-section-number">17</span> Annex: controversial design decisions<span></span></a><ul>
                <li><a href="#size-of-function_ref"><span class="toc-section-number">17.1</span> Size of <code>function_ref</code><span></span></a></li>
                <li><a href="#lifetime-of-pointers-to-function"><span class="toc-section-number">17.2</span> Lifetime of pointers to function<span></span></a></li>
                <li><a href="#assignment-operator"><span class="toc-section-number">17.3</span> Assignment operator<span></span></a></li>
                <li><a href="#reference_wrapper-unwrapping"><span class="toc-section-number">17.4</span> <code>reference_wrapper</code> unwrapping<span></span></a></li>
                </ul></li>
                <li><a href="#annex-existing-practice-survey"><span class="toc-section-number">18</span> Annex: existing practice survey<span></span></a></li>
                <li><a href="#references"><span class="toc-section-number">19</span> References<span></span></a></li>
                </ul>
            </div>
             <style>
.inline-link
{
    font-size: small;
    margin-top: -2.8em;
    margin-right: 4px;
    text-align: right;
    font-weight: bold;
}

code
{
    font-family: "Fira Code", monospace !important;
    font-size: 0.87em;
}

.sourceCode
{
    font-size: 0.95em;
}

a code
{
    color: #0645ad;
}
</style>
<h1 id="abstract"><span class="header-section-number">1</span> Abstract<a href="#abstract" class="self-link"></a></h1>
<p>This paper proposes the addition of <code>function_ref&lt;R(Args...)&gt;</code> to the Standard Library, a <em>“vocabulary type”</em> for non-owning references to <code>Callable</code> objects.</p>
<h1 id="changelog-and-polls"><span class="header-section-number">2</span> Changelog and polls<a href="#changelog-and-polls" class="self-link"></a></h1>
<h2 id="r5"><span class="header-section-number">2.1</span> R5<a href="#r5" class="self-link"></a></h2>
<ul>
<li><p>Removed “qualifiers” from <code>operator()</code> specification (typo);</p></li>
<li><p>Added <em>“Annex: controversial design decisions”</em>;</p></li>
<li><p>Added <em>“Annex: existing practice survey”</em>;</p></li>
<li><p>Changed <em>“has a noexcept specifier”</em> to <em>“has a non-throwing exception specification”</em> in the specification of the constructor and assignment.</p></li>
</ul>
<h2 id="r4"><span class="header-section-number">2.2</span> R4<a href="#r4" class="self-link"></a></h2>
<ul>
<li><p>Stripped qualifiers from exposition-only <code>erased_fn_type</code>;</p></li>
<li><p>Removed <code>constexpr</code> due to implementation concerns - this can be re-introduced in a future paper;</p></li>
<li><p>Changed wording to give instructions to the editor;</p></li>
<li><p>Added paragraph numbers and reordered sections;</p></li>
<li><p>Added brief before-class synopsis;</p></li>
<li><p>Added an explicit bullet point for trivial copyability;</p></li>
<li><p>Removed defaulted functions (copy constructor and assignment) from specification;</p></li>
<li><p>Reworded specification following P1369;</p></li>
<li><p>Mention exposition-only members in template constructor;</p></li>
<li><p>Add “see below” to <code>noexcept</code> on <code>operator()</code>.</p></li>
</ul>
<h2 id="r3"><span class="header-section-number">2.3</span> R3<a href="#r3" class="self-link"></a></h2>
<ul>
<li><p>Removed <code>!f</code> precondition for construction/assignment from <code>std::function</code> <code>f</code>;</p></li>
<li><p><code>function_ref::operator()</code> is now unconditionally <code>const</code>-qualified.</p></li>
</ul>
<h3 id="polls"><span class="header-section-number">2.3.1</span> Polls<a href="#polls" class="self-link"></a></h3>
<blockquote>
<p>Do we want to remove the precondition that <code>!f</code> must hold when <code>function_ref</code> is constructed/assigned from an instance of <code>std::function</code> <code>f</code>?</p>
<p>SF F N A SA</p>
<p>1 8 1 0 0</p>
</blockquote>
<blockquote>
<p>Should <code>function_ref::operator()</code> be unconditionally <code>const</code>-qualified?</p>
<p>SF F N A SA</p>
<p>8 2 0 1 0</p>
</blockquote>
<blockquote>
<p>Should <code>function_ref</code> fully support the <code>Callable</code> concept at the potential cost of <code>sizeof(function_ref) &gt; sizeof(void(*)()) * 2</code>?</p>
<p>SF F N A SA</p>
<p>6 4 0 0 0</p>
</blockquote>
<h2 id="r2"><span class="header-section-number">2.4</span> R2<a href="#r2" class="self-link"></a></h2>
<ul>
<li><p>Made <em>copy constructor</em> and <em>copy assignment</em> <code>= default</code>;</p></li>
<li><p>Changed uses of <code>std::decay_t</code> to <code>std::remove_cvref_t</code>;</p></li>
<li><p>Added “exposition only” <code>void*</code> and <em>pointer to function</em> data members;</p></li>
<li><p>Moved <em>“Open questions”</em> section to <em>“Annex: previously open questions”</em>;</p></li>
<li><p>Change <code>function_ref(F&amp;&amp;)</code> constructor’s precondition to use <code>remove_cvref_t</code> to check if <code>F</code> is an instance of the <code>function</code> class template;</p></li>
<li><p>Dropped <code>function_ref&lt;Signature&gt;::</code> qualification in member function specification.</p></li>
</ul>
<h3 id="polls-1"><span class="header-section-number">2.4.1</span> Polls<a href="#polls-1" class="self-link"></a></h3>
<blockquote>
<p>We want to prevent construction of std::function from std::function_ref (but not other callable-taking things like std::bind).</p>
<p>SF F N A SA</p>
<p>0 0 4 8 0</p>
</blockquote>
<blockquote>
<p>We want to revise the paper to include discussion of ref-qualified callables.</p>
<p>SF F N A SA</p>
<p>0 3 6 6 0</p>
</blockquote>
<blockquote>
<p>Forward paper as-is to LWG for C++20?</p>
<p>SF F N A SA</p>
<p>3 9 3 0 0</p>
</blockquote>
<h2 id="r1"><span class="header-section-number">2.5</span> R1<a href="#r1" class="self-link"></a></h2>
<ul>
<li><p>Removed empty state and comparisons with <code>nullptr</code>;</p></li>
<li><p>Removed default constructor;</p></li>
<li><p>Added support for <code>noexcept</code> and <code>const</code>-qualified function signatures <em>(these are propagated to <code>function_ref::operator()</code>)</em>;</p></li>
<li><p>Added deduction guides for function pointers and arbitrary callable objects with well-formed <code>&amp;remove_reference_t&lt;F&gt;::operator()</code>;</p></li>
<li><p>Added two new bullet points to “Open questions”;</p></li>
<li><p>Added “Example implementation”;</p></li>
<li><p>Added “Feature test macro”;</p></li>
<li><p>Removed <code>noexcept</code> from constructor and assignment.</p></li>
</ul>
<h3 id="polls-2"><span class="header-section-number">2.5.1</span> Polls<a href="#polls-2" class="self-link"></a></h3>
<h4 id="semantics-pointer-versus-reference"><span class="header-section-number">2.5.1.1</span> Semantics: pointer versus reference<a href="#semantics-pointer-versus-reference" class="self-link"></a></h4>
<blockquote>
<p>option 1</p>
<p>function_ref, non-nullable, not default constructible</p>
<p>option 2</p>
<p>function_ptr, nullable, default constructible</p>
<p>We want 1 and 2</p>
<p>SF F N A SA</p>
<p>1 2 8 3 6</p>
<p>ref vs ptr</p>
<p>SR R N P SP</p>
<p>6 5 2 5 0</p>
</blockquote>
<p>The poll above clearly shows that the desired direction for <code>function_ref</code> is towards a <em>non nullable</em>, <em>non default-constructible</em> reference type. This revision (P0792R2) removes the “empty state” and default constructibility from the proposed <code>function_ref</code>. If those semantics are required by users, they can trivially wrap <code>function_ref</code> into an <code>std::optional&lt;function_ref&lt;/* ... */&gt;&gt;</code>.</p>
<h4 id="target-and-target_type"><span class="header-section-number">2.5.1.2</span> <code>target</code> and <code>target_type</code><a href="#target-and-target_type" class="self-link"></a></h4>
<blockquote>
<p>We want target and target-type (consistent with std::function) if they have no overhead</p>
<p>Unanimous consent</p>
<p>We want target and target-type (consistent with std::function) even though they have overhead</p>
<p>SF F N A SA</p>
<p>0 0 1 9 4</p>
</blockquote>
<p>I am not sure whether <code>target</code> and <code>target_type</code> can be implemented without introducing overhead. I seek the guidance of the committee or any interested reader to figure that out. If they require overhead, I agree with the poll: they will be left out of the proposal.</p>
<h1 id="overview"><span class="header-section-number">3</span> Overview<a href="#overview" class="self-link"></a></h1>
<p>Since the advent of C++11 writing more functional code has become easier: functional programming patterns and idioms have become powerful additions to the C++ developer’s toolbox. <strong>“Higher-order functions”</strong> are one of the key ideas of the functional paradigm - in short, they are functions that take functions as arguments and/or return functions as results.</p>
<p>The need of referring to an existing <code>Callable</code> object comes up often when writing functional C++ code, but the Standard Library unfortunately doesn’t provide a flexible facility that allows to do so. Let’s consider the existing utilities:</p>
<ul>
<li><p><strong>Pointers to functions</strong> are only useful when the entity they refer to is stateless <em>(i.e. a non-member function or a capture-less lambda)</em>, but they are cumbersome to use otherwise. Fully supporting the <code>Callable</code> concept requires also explicitly dealing with <strong>pointers to member functions</strong> and <strong>pointers to data members</strong>.</p></li>
<li><p><strong><code>std::function</code></strong> seamlessly works with <code>Callable</code> objects, but it’s a <em>“general-purpose polymorphic function wrapper”</em> that may introduce unnecessary overhead and that <strong>owns</strong> the <code>Callable</code> it stores. <code>std::function</code> is a great choice when an owning type-erased wrapper is required, but it’s often abused when its ownership semantics and its flexibility are not required.</p>
<ul>
<li><p>Note that when <code>std::function</code> is constructed/assigned with a <code>std::reference_wrapper</code> to a <code>Callable</code>, it has reference semantics.</p></li>
<li><p>Another limitation of <code>std::function</code> is the fact that the stored <code>Callable</code> must be <code>CopyConstructible</code>.</p></li>
</ul></li>
<li><p><strong>Templates</strong> can be used to avoid unnecessary costs and to uniformly handle any <code>Callable</code> object, but they are hard to constrain to a particular signature and force code to be defined in headers.</p></li>
</ul>
<p>This paper proposes the introduction of a new <code>function_ref</code> class template, which is akin to <code>std::string_view</code>. This paper describes <code>function_ref</code> as a <strong>non-owning lightweight wrapper</strong> over any <code>Callable</code> object.</p>
<h1 id="motivating-example"><span class="header-section-number">4</span> Motivating example<a href="#motivating-example" class="self-link"></a></h1>
<p>Here’s one example use case that benefits from <em>higher-order functions</em>: a <code>retry(n, f)</code> function that attempts to synchronously call <code>f</code> up to <code>n</code> times until success. This example might model the real-world scenario of repeatedly querying a flaky web service.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb1-1"><a href="#cb1-1"></a><span class="kw">struct</span> payload <span class="op">{</span> <span class="co">/* ... */</span> <span class="op">}</span>;</span>
<span id="cb1-2"><a href="#cb1-2"></a></span>
<span id="cb1-3"><a href="#cb1-3"></a><span class="co">// Repeatedly invokes `action` up to `times` repetitions.</span></span>
<span id="cb1-4"><a href="#cb1-4"></a><span class="co">// Immediately returns if `action` returns a valid `payload`.</span></span>
<span id="cb1-5"><a href="#cb1-5"></a><span class="co">// Returns `std::nullopt` otherwise.</span></span>
<span id="cb1-6"><a href="#cb1-6"></a>std<span class="op">::</span>optional<span class="op">&lt;</span>payload<span class="op">&gt;</span> retry<span class="op">(</span>std<span class="op">::</span><span class="dt">size_t</span> times, <span class="co">/* ????? */</span> action<span class="op">)</span>;</span></code></pre></div>
<p>The passed-in <code>action</code> should be a <code>Callable</code> which takes no arguments and returns <code>std::optional&lt;payload&gt;</code>. Let’s see how <code>retry</code> can be implemented with various techniques:</p>
<ul>
<li><p>Using <em>pointers to functions</em>:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb2-1"><a href="#cb2-1"></a>std<span class="op">::</span>optional<span class="op">&lt;</span>payload<span class="op">&gt;</span> retry<span class="op">(</span>std<span class="op">::</span><span class="dt">size_t</span> times,</span>
<span id="cb2-2"><a href="#cb2-2"></a>                             std<span class="op">::</span>optional<span class="op">&lt;</span>payload<span class="op">&gt;(*</span>action<span class="op">)())</span></span>
<span id="cb2-3"><a href="#cb2-3"></a><span class="op">{</span></span>
<span id="cb2-4"><a href="#cb2-4"></a>    <span class="co">/* ... */</span></span>
<span id="cb2-5"><a href="#cb2-5"></a><span class="op">}</span></span></code></pre></div>
<div class="inline-link">
<p><a href="https://godbolt.org/g/UQbZYp"><em>(on godbolt.org)</em></a></p>
</div>
<ul>
<li><p><strong>Advantages</strong>:</p>
<ul>
<li><p>Easy to implement: no need to use a <code>template</code> or any explicit constraint <em>(e.g. <code>std::enable_if_t&lt;...&gt;</code>)</em>. The type of the pointer specifies exactly which functions can be passed, no extra constraints are required.</p></li>
<li><p>Minimal overhead: no allocations, no exceptions, and <code>action</code> is as big as a pointer.</p>
<ul>
<li>Modern compilers are able to completely inline the call to <code>action</code>, producing optimal assembly.</li>
</ul></li>
</ul></li>
<li><p><strong>Drawbacks</strong>:</p>
<ul>
<li>This technique doesn’t support stateful <code>Callable</code> objects.</li>
</ul></li>
</ul></li>
<li><p>Using a <code>template</code>:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb3-1"><a href="#cb3-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> F<span class="op">&gt;</span></span>
<span id="cb3-2"><a href="#cb3-2"></a><span class="kw">auto</span> retry<span class="op">(</span>std<span class="op">::</span><span class="dt">size_t</span> times, F<span class="op">&amp;&amp;</span> action<span class="op">)</span></span>
<span id="cb3-3"><a href="#cb3-3"></a>    <span class="op">-&gt;</span> std<span class="op">::</span>enable_if_t<span class="op">&lt;</span>std<span class="op">::</span>is_invocable_r_v<span class="op">&lt;</span>std<span class="op">::</span>optional<span class="op">&lt;</span>payload<span class="op">&gt;</span>, F<span class="op">&amp;&amp;&gt;</span>,</span>
<span id="cb3-4"><a href="#cb3-4"></a>                        std<span class="op">::</span>optional<span class="op">&lt;</span>payload<span class="op">&gt;&gt;</span></span>
<span id="cb3-5"><a href="#cb3-5"></a><span class="op">{</span></span>
<span id="cb3-6"><a href="#cb3-6"></a>    <span class="co">/* ... */</span></span>
<span id="cb3-7"><a href="#cb3-7"></a><span class="op">}</span></span></code></pre></div>
<div class="inline-link">
<p><a href="https://godbolt.org/g/AGikkz"><em>(on godbolt.org)</em></a></p>
</div>
<ul>
<li><p><strong>Advantages</strong>:</p>
<ul>
<li><p>Supports arbitrary <code>Callable</code> objects, such as stateful closures.</p></li>
<li><p>Zero-overhead: no allocations, no exceptions, no indirections.</p></li>
</ul></li>
<li><p><strong>Drawbacks</strong>:</p>
<ul>
<li><p>Harder to implement and less readable: users must use <code>std::enable_if_t</code> and <code>std::invocable_r_v</code> to ensure that <code>action</code>’s signature is properly constrained.</p></li>
<li><p><code>retry</code> must be defined in a header file. This might be undesiderable when trying to minimize compilation times.</p></li>
</ul></li>
</ul></li>
<li><p>Using <code>std::function</code>:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb4-1"><a href="#cb4-1"></a>std<span class="op">::</span>optional<span class="op">&lt;</span>payload<span class="op">&gt;</span> retry<span class="op">(</span>std<span class="op">::</span><span class="dt">size_t</span> times,</span>
<span id="cb4-2"><a href="#cb4-2"></a>                             std<span class="op">::</span>function<span class="op">&lt;</span>std<span class="op">::</span>optional<span class="op">&lt;</span>payload<span class="op">&gt;()&gt;</span> action<span class="op">)</span></span>
<span id="cb4-3"><a href="#cb4-3"></a><span class="op">{</span></span>
<span id="cb4-4"><a href="#cb4-4"></a>    <span class="co">/* ... */</span></span>
<span id="cb4-5"><a href="#cb4-5"></a><span class="op">}</span></span></code></pre></div>
<div class="inline-link">
<p><a href="https://godbolt.org/g/t9FH9b"><em>(on godbolt.org)</em></a></p>
</div>
<ul>
<li><p><strong>Advantages</strong>:</p>
<ul>
<li><p>Supports arbitrary <code>Callable</code> objects, such as stateful closures.</p></li>
<li><p>Easy to implement: no need to use a <code>template</code> or any explicit constraint. The type fully constrains what can be passed.</p></li>
</ul></li>
<li><p><strong>Drawbacks</strong>:</p>
<ul>
<li><p>Unclear ownership semantics: <code>action</code> might either own the the stored <code>Callable</code>, or just refer to an existing <code>Callable</code> if initialized with a <code>std::reference_wrapper</code>.</p></li>
<li><p>Can potentially have significant overhead:</p>
<ul>
<li><p>Even though the implementation makes use of SBO <em>(small buffer optimization)</em>, <code>std::function</code> might allocate if the stored object is large enough. This requires one extra branch on construction/assignment, one potential dynamic allocation, and makes <code>action</code> as big as the size of the internal buffer.</p></li>
<li><p>If the implementation doesn’t make use of SBO, <code>std::function</code> will always allocate on construction/assignment.</p></li>
<li><p>Modern compilers are not able to inline <code>std::function</code>, often resulting in very poor assembly compared to the previously mentioned techniques.</p></li>
</ul></li>
<li><p>Mandatory use of exceptions: <code>std::function</code> might throw if an allocation fails, and throws <code>std::bad_function_call</code> if it’s invoked while unset.</p></li>
</ul></li>
</ul></li>
<li><p>Using the proposed <code>function_ref</code>:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb5-1"><a href="#cb5-1"></a>std<span class="op">::</span>optional<span class="op">&lt;</span>payload<span class="op">&gt;</span> retry<span class="op">(</span>std<span class="op">::</span><span class="dt">size_t</span> times,</span>
<span id="cb5-2"><a href="#cb5-2"></a>                             function_ref<span class="op">&lt;</span>std<span class="op">::</span>optional<span class="op">&lt;</span>payload<span class="op">&gt;()&gt;</span> action<span class="op">)</span></span>
<span id="cb5-3"><a href="#cb5-3"></a><span class="op">{</span></span>
<span id="cb5-4"><a href="#cb5-4"></a>    <span class="co">/* ... */</span></span>
<span id="cb5-5"><a href="#cb5-5"></a><span class="op">}</span></span></code></pre></div>
<div class="inline-link">
<p><a href="https://godbolt.org/g/DvWKVH"><em>(on godbolt.org)</em></a></p>
</div>
<ul>
<li><p><strong>Advantages</strong>:</p>
<ul>
<li><p>Supports arbitrary <code>Callable</code> objects, such as stateful closures.</p></li>
<li><p>Easy to implement: no need to use a <code>template</code> or any constraint. The type fully constrains what can be passed.</p></li>
<li><p>Clear ownership semantics: <code>action</code> is a <strong>non-owning</strong> reference to an existing <code>Callable</code>.</p></li>
<li><p>Small overhead: no allocations, no exceptions, and <code>action</code> is as big as two pointers.</p>
<ul>
<li>Modern compilers are able to completely inline the call to <code>action</code>, producing optimal assembly.</li>
</ul></li>
</ul></li>
</ul></li>
</ul>
<h1 id="impact-on-the-standard"><span class="header-section-number">5</span> Impact on the Standard<a href="#impact-on-the-standard" class="self-link"></a></h1>
<p>This proposal is a pure library extension. It does not require changes to any existing part of the Standard.</p>
<h1 id="alternatives"><span class="header-section-number">6</span> Alternatives<a href="#alternatives" class="self-link"></a></h1>
<p>The only existing viable alternative to <code>function_ref</code> currently is <code>std::function</code> + <code>std::reference_wrapper</code>. The Standard guarantees that when a <code>std::reference_wrapper</code> is used to construct/assign to a <code>std::function</code> no allocations will occur and no exceptions will be thrown.</p>
<p>Using <code>std::function</code> for non-owning references is suboptimal for various reasons.</p>
<ol type="1">
<li><p>The ownership semantics of a <code>std::function</code> are unclear - they change depending on whether or not the <code>std::function</code> was constructed/assigned with a <code>std::reference_wrapper</code>.</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb6-1"><a href="#cb6-1"></a><span class="dt">void</span> foo<span class="op">(</span>std<span class="op">::</span>function<span class="op">&lt;</span><span class="dt">void</span><span class="op">()&gt;</span> f<span class="op">)</span>;</span>
<span id="cb6-2"><a href="#cb6-2"></a><span class="co">// `f` could be referring to an existing Callable, or could own one.</span></span>
<span id="cb6-3"><a href="#cb6-3"></a></span>
<span id="cb6-4"><a href="#cb6-4"></a><span class="dt">void</span> bar<span class="op">(</span>function_ref<span class="op">&lt;</span><span class="dt">void</span><span class="op">()&gt;</span> f<span class="op">)</span>;</span>
<span id="cb6-5"><a href="#cb6-5"></a><span class="co">// `f` unambiguously is a non-owning reference to an existing Callable.</span></span></code></pre></div></li>
<li><p>This technique doesn’t work with temporaries. This is a huge drawback as it prevents stateful temporary lambdas from being passed as callbacks.</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb7-1"><a href="#cb7-1"></a><span class="dt">void</span> foo<span class="op">(</span>std<span class="op">::</span>function<span class="op">&lt;</span><span class="dt">void</span><span class="op">()&gt;</span> f<span class="op">)</span>;</span>
<span id="cb7-2"><a href="#cb7-2"></a></span>
<span id="cb7-3"><a href="#cb7-3"></a><span class="dt">int</span> main<span class="op">()</span></span>
<span id="cb7-4"><a href="#cb7-4"></a><span class="op">{</span></span>
<span id="cb7-5"><a href="#cb7-5"></a>    <span class="dt">int</span> x <span class="op">=</span> <span class="dv">0</span>;</span>
<span id="cb7-6"><a href="#cb7-6"></a>    foo<span class="op">(</span>std<span class="op">::</span>ref<span class="op">([&amp;</span>x<span class="op">]{</span> <span class="op">++</span>x; <span class="op">})</span>; <span class="co">// does not compile</span></span>
<span id="cb7-7"><a href="#cb7-7"></a><span class="op">}</span></span></code></pre></div>
<div class="inline-link">
<p><a href="https://godbolt.org/g/DPQ7ku"><em>(on godbolt.org)</em></a></p>
</div>
<p>The code above doesn’t compile, as <code>std::ref</code> only accepts non-<code>const</code> lvalue references <em>(additionally, <code>std::cref</code> is explicitly deleted for rvalue references)</em>. Avoiding the use of <code>std::ref</code> breaks the guarantee that <code>f</code> won’t allocate or throw an exception on construction.</p></li>
<li><p><code>std::function</code> is harder for compilers to optimize compared to the proposed <code>function_ref</code>. This is true due to various reasons:</p>
<ul>
<li><p><code>std::function</code> can allocate and/or throw exceptions on construction and/or assigment.</p></li>
<li><p><code>std::function</code> might use SBO, which could require an additional branch during construction/assignment, make inlining more difficult, and unnecessarily increase memory usage.</p></li>
</ul>
<p>Rough benchmarks comparing the generated assembly of a <em><code>std::function</code> parameter</em> and a <em><code>function_ref</code> parameter</em> against a <em>template parameter</em> show that:</p>
<ul>
<li><p><code>std::function</code>, on average, generates approximately 5x more assembly than a template parameter.</p></li>
<li><p><code>function_ref</code>, on average, generates approximately 1.5x more assembly than a template parameter.</p></li>
</ul>
<p>A description of the benchmarking techniques used and the full results can be found on my article <em>“passing functions to functions”</em>.<a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a></p></li>
</ol>
<h1 id="changes-to-functional-header"><span class="header-section-number">7</span> Changes to <code>&lt;functional&gt;</code> header<a href="#changes-to-functional-header" class="self-link"></a></h1>
<p>Add the following to <code>[functional.syn]</code>:</p>
<blockquote>
<div class="sourceCode" id="cb8"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb8-1"><a href="#cb8-1"></a><span class="kw">namespace</span> std</span>
<span id="cb8-2"><a href="#cb8-2"></a><span class="op">{</span></span>
<span id="cb8-3"><a href="#cb8-3"></a>    <span class="co">// ...</span></span>
<span id="cb8-4"><a href="#cb8-4"></a></span>
<span id="cb8-5"><a href="#cb8-5"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> Signature<span class="op">&gt;</span> <span class="kw">class</span> function_ref;</span>
<span id="cb8-6"><a href="#cb8-6"></a></span>
<span id="cb8-7"><a href="#cb8-7"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> Signature<span class="op">&gt;</span></span>
<span id="cb8-8"><a href="#cb8-8"></a>    <span class="dt">void</span> swap<span class="op">(</span>function_ref<span class="op">&lt;</span>Signature<span class="op">&gt;&amp;</span> lhs, function_ref<span class="op">&lt;</span>Signature<span class="op">&gt;&amp;</span> rhs<span class="op">)</span> <span class="kw">noexcept</span>;</span>
<span id="cb8-9"><a href="#cb8-9"></a></span>
<span id="cb8-10"><a href="#cb8-10"></a>    <span class="co">// ...</span></span>
<span id="cb8-11"><a href="#cb8-11"></a><span class="op">}</span></span></code></pre></div>
</blockquote>
<h1 id="class-synopsis"><span class="header-section-number">8</span> Class synopsis<a href="#class-synopsis" class="self-link"></a></h1>
<p>Create a new section “Class template <code>function_ref</code>”, <code>[functionref]</code>&quot; with the following:</p>
<blockquote>
<div class="sourceCode" id="cb9"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb9-1"><a href="#cb9-1"></a><span class="kw">namespace</span> std</span>
<span id="cb9-2"><a href="#cb9-2"></a><span class="op">{</span></span>
<span id="cb9-3"><a href="#cb9-3"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> Signature<span class="op">&gt;</span></span>
<span id="cb9-4"><a href="#cb9-4"></a>    <span class="kw">class</span> function_ref</span>
<span id="cb9-5"><a href="#cb9-5"></a>    <span class="op">{</span></span>
<span id="cb9-6"><a href="#cb9-6"></a>        <span class="dt">void</span><span class="op">*</span> erased_object; <span class="co">// exposition only</span></span>
<span id="cb9-7"><a href="#cb9-7"></a></span>
<span id="cb9-8"><a href="#cb9-8"></a>        R<span class="op">(*</span>erased_function<span class="op">)(</span>Args<span class="op">...)</span>; <span class="co">// exposition only</span></span>
<span id="cb9-9"><a href="#cb9-9"></a>        <span class="co">// `R`, and `Args...` are the return type, and the parameter-type-list,</span></span>
<span id="cb9-10"><a href="#cb9-10"></a>        <span class="co">// of the function type `Signature`, respectively.</span></span>
<span id="cb9-11"><a href="#cb9-11"></a></span>
<span id="cb9-12"><a href="#cb9-12"></a>    <span class="kw">public</span><span class="op">:</span></span>
<span id="cb9-13"><a href="#cb9-13"></a>        function_ref<span class="op">(</span><span class="kw">const</span> function_ref<span class="op">&amp;)</span> <span class="kw">noexcept</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb9-14"><a href="#cb9-14"></a></span>
<span id="cb9-15"><a href="#cb9-15"></a>        <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> F<span class="op">&gt;</span></span>
<span id="cb9-16"><a href="#cb9-16"></a>        function_ref<span class="op">(</span>F<span class="op">&amp;&amp;)</span>;</span>
<span id="cb9-17"><a href="#cb9-17"></a></span>
<span id="cb9-18"><a href="#cb9-18"></a>        function_ref<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">=(</span><span class="kw">const</span> function_ref<span class="op">&amp;)</span> <span class="kw">noexcept</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb9-19"><a href="#cb9-19"></a></span>
<span id="cb9-20"><a href="#cb9-20"></a>        <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> F<span class="op">&gt;</span></span>
<span id="cb9-21"><a href="#cb9-21"></a>        function_ref<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">=(</span>F<span class="op">&amp;&amp;)</span>;</span>
<span id="cb9-22"><a href="#cb9-22"></a></span>
<span id="cb9-23"><a href="#cb9-23"></a>        <span class="dt">void</span> swap<span class="op">(</span>function_ref<span class="op">&amp;)</span> <span class="kw">noexcept</span>;</span>
<span id="cb9-24"><a href="#cb9-24"></a></span>
<span id="cb9-25"><a href="#cb9-25"></a>        R <span class="kw">operator</span><span class="op">()(</span>Args<span class="op">...)</span> <span class="kw">const</span> <span class="kw">noexcept</span><span class="op">(</span><em>see below</em><span class="op">)</span>;</span>
<span id="cb9-26"><a href="#cb9-26"></a>        <span class="co">// `R` and `Args...` are the return type and the parameter-type-list</span></span>
<span id="cb9-27"><a href="#cb9-27"></a>        <span class="co">// of the function type `Signature`, respectively.</span></span>
<span id="cb9-28"><a href="#cb9-28"></a>    <span class="op">}</span>;</span>
<span id="cb9-29"><a href="#cb9-29"></a></span>
<span id="cb9-30"><a href="#cb9-30"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> Signature<span class="op">&gt;</span></span>
<span id="cb9-31"><a href="#cb9-31"></a>    <span class="dt">void</span> swap<span class="op">(</span>function_ref<span class="op">&lt;</span>Signature<span class="op">&gt;&amp;</span>, function_ref<span class="op">&lt;</span>Signature<span class="op">&gt;&amp;)</span> <span class="kw">noexcept</span>;</span>
<span id="cb9-32"><a href="#cb9-32"></a></span>
<span id="cb9-33"><a href="#cb9-33"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> R, <span class="kw">typename</span><span class="op">...</span> Args<span class="op">&gt;</span></span>
<span id="cb9-34"><a href="#cb9-34"></a>    function_ref<span class="op">(</span>R <span class="op">(*)(</span>Args<span class="op">...))</span> <span class="op">-&gt;</span> function_ref<span class="op">&lt;</span>R<span class="op">(</span>Args<span class="op">...)&gt;</span>;</span>
<span id="cb9-35"><a href="#cb9-35"></a></span>
<span id="cb9-36"><a href="#cb9-36"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> R, <span class="kw">typename</span><span class="op">...</span> Args<span class="op">&gt;</span></span>
<span id="cb9-37"><a href="#cb9-37"></a>    function_ref<span class="op">(</span>R <span class="op">(*)(</span>Args<span class="op">...)</span> <span class="kw">noexcept</span><span class="op">)</span> <span class="op">-&gt;</span> function_ref<span class="op">&lt;</span>R<span class="op">(</span>Args<span class="op">...)</span> <span class="kw">noexcept</span><span class="op">&gt;</span>;</span>
<span id="cb9-38"><a href="#cb9-38"></a></span>
<span id="cb9-39"><a href="#cb9-39"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> F<span class="op">&gt;</span></span>
<span id="cb9-40"><a href="#cb9-40"></a>    function_ref<span class="op">(</span>F<span class="op">)</span> <span class="op">-&gt;</span> function_ref<span class="op">&lt;</span><em>see below</em><span class="op">&gt;</span>;</span>
<span id="cb9-41"><a href="#cb9-41"></a><span class="op">}</span></span></code></pre></div>
<ol type="1">
<li><p><code>function_ref&lt;Signature&gt;</code> is a <code>Cpp17CopyConstructible</code> and <code>Cpp17CopyAssignable</code> reference to an <code>Invocable</code> object with signature <code>Signature</code>.</p></li>
<li><p><code>function_ref&lt;Signature&gt;</code> is a trivially copyable type.</p></li>
<li><p>The template argument <code>Signature</code> shall be a non-<code>volatile</code>-qualified function type.</p></li>
</ol>
</blockquote>
<h1 id="specification"><span class="header-section-number">9</span> Specification<a href="#specification" class="self-link"></a></h1>
<div class="sourceCode" id="cb10"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb10-1"><a href="#cb10-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> F<span class="op">&gt;</span></span>
<span id="cb10-2"><a href="#cb10-2"></a>function_ref<span class="op">(</span>F<span class="op">&amp;&amp;</span> f<span class="op">)</span>;</span></code></pre></div>
<ul>
<li><p><em>Constraints:</em> <code>is_same_v&lt;remove_cvref_t&lt;F&gt;, function_ref&gt;</code> is <code>false</code> and</p>
<ul>
<li><p>If <code>Signature</code> has a non-throwing exception specification: <code>is_nothrow_invocable_r_v&lt;R, cv-qualifiers F&amp;, Args...&gt;</code> is <code>true</code>;</p></li>
<li><p>Otherwise: <code>is_invocable_r_v&lt;R, cv-qualifiers F&amp;, Args...&gt;</code> is <code>true</code>.</p></li>
</ul>
<p>Where <code>R</code>, <code>Args...</code>, and <code>cv-qualifiers</code> are the <em>return type</em>, the <em>parameter-type-list</em>, and the sequence “<em>cv-qualifier-seq-opt</em>” of the function type <code>Signature</code>, respectively.</p></li>
<li><p><em>Expects:</em> <code>f</code> is neither a null function pointer value nor a null member pointer value.</p></li>
<li><p><em>Effects:</em> Constructs a <code>function_ref</code> referring to <code>f</code>.</p></li>
<li><p><em>Remarks:</em> <code>erased_object</code> will point to <code>f</code>. <code>erased_function</code> will point to a function whose invocation is equivalent to <code>return INVOKE&lt;R&gt;(f, std::forward&lt;Args&gt;(xs)...);</code>, where <code>f</code> is qualified with the same <em>cv-qualifiers</em> as the function type <code>Signature</code>.</p></li>
</ul>
<p><br></p>
<div class="sourceCode" id="cb11"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb11-1"><a href="#cb11-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> F<span class="op">&gt;</span></span>
<span id="cb11-2"><a href="#cb11-2"></a>function_ref<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">=(</span>F<span class="op">&amp;&amp;)</span>;</span></code></pre></div>
<ul>
<li><p><em>Constraints:</em> <code>is_same_v&lt;remove_cvref_t&lt;F&gt;, function_ref&gt;</code> is <code>false</code> and</p>
<ul>
<li><p>If <code>Signature</code> has a non-throwing exception specification: <code>is_nothrow_invocable_r_v&lt;R, cv-qualifiers F&amp;, Args...&gt;</code> is <code>true</code>;</p></li>
<li><p>Otherwise: <code>is_invocable_r_v&lt;R, cv-qualifiers F&amp;, Args...&gt;</code> is <code>true</code>.</p></li>
</ul>
<p>Where <code>R</code>, <code>Args...</code>, and <code>cv-qualifiers</code> are the <em>return type</em>, the <em>parameter-type-list</em>, and the sequence “<em>cv-qualifier-seq-opt</em>” of the function type <code>Signature</code>, respectively.</p></li>
<li><p><em>Expects:</em> <code>f</code> is neither a null function pointer value nor a null member pointer value.</p></li>
<li><p><em>Ensures:</em> <code>*this</code> refers to <code>f</code>.</p></li>
<li><p><em>Returns:</em> <code>*this</code>.</p></li>
</ul>
<p><br></p>
<div class="sourceCode" id="cb12"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb12-1"><a href="#cb12-1"></a><span class="dt">void</span> swap<span class="op">(</span>function_ref<span class="op">&amp;</span> rhs<span class="op">)</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<ul>
<li><em>Effects:</em> Exchanges the values of <code>*this</code> and <code>rhs</code>.</li>
</ul>
<p><br></p>
<div class="sourceCode" id="cb13"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb13-1"><a href="#cb13-1"></a>R <span class="kw">operator</span><span class="op">()(</span>Args<span class="op">...</span> xs<span class="op">)</span> <span class="kw">noexcept</span><span class="op">(</span><em>see below</em><span class="op">)</span>;</span></code></pre></div>
<ul>
<li><p><em>Effects:</em> Equivalent to <code>return INVOKE&lt;R&gt;(f, std::forward&lt;Args&gt;(xs)...);</code>, where <code>f</code> is the callable object referred to by <code>*this</code>, qualified with the same <em>cv-qualifiers</em> as the function type <code>Signature</code>.</p></li>
<li><p><em>Remarks:</em> <code>R</code> and <code>Args...</code> are the return type and the parameter-type-list of the function type <code>Signature</code>, respectively. The expression inside <code>noexcept</code> is the sequence “noexcept-specifier-opt” of the function type <code>Signature</code>.</p></li>
</ul>
<p><br></p>
<div class="sourceCode" id="cb14"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb14-1"><a href="#cb14-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> F<span class="op">&gt;</span></span>
<span id="cb14-2"><a href="#cb14-2"></a>function_ref<span class="op">(</span>F<span class="op">)</span> <span class="op">-&gt;</span> function_ref<span class="op">&lt;</span><em>see below</em><span class="op">&gt;</span>;</span></code></pre></div>
<ul>
<li><p><em>Constraints:</em> <code>&amp;F::operator()</code> is well-formed when treated as an unevaluated operand.</p></li>
<li><p><em>Remarks:</em> If <code>decltype(&amp;F::operator())</code> is of the form <code>R(G::*)(A...) qualifiers</code> for a class type <code>G</code>, then the deduced type is <code>function_ref&lt;R(A...) qualifiers&gt;</code>.</p></li>
</ul>
<p><br></p>
<div class="sourceCode" id="cb15"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb15-1"><a href="#cb15-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> Signature<span class="op">&gt;</span></span>
<span id="cb15-2"><a href="#cb15-2"></a><span class="dt">void</span> swap<span class="op">(</span>function_ref<span class="op">&lt;</span>Signature<span class="op">&gt;&amp;</span> lhs, function_ref<span class="op">&lt;</span>Signature<span class="op">&gt;&amp;</span> rhs<span class="op">)</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<ul>
<li><em>Effects:</em> Equivalent to <code>lhs.swap(rhs)</code>.</li>
</ul>
<p><br></p>
<h1 id="feature-test-macro"><span class="header-section-number">10</span> Feature test macro<a href="#feature-test-macro" class="self-link"></a></h1>
<p>Append to §17.3.1 General <code>[support.limits.general]</code>’s Table 36 one additional entry:</p>
<table>
<thead>
<tr class="header">
<th><div style="text-align:center">
<strong>Macro name</strong>
</div></th>
<th><div style="text-align:center">
<strong>Value</strong>
</div></th>
<th><div style="text-align:center">
<strong>Headers</strong>
</div></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>__cpp_lib_function_ref</td>
<td>201811L</td>
<td><code>&lt;functional&gt;</code></td>
</tr>
</tbody>
</table>
<h1 id="example-implementation"><span class="header-section-number">11</span> Example implementation<a href="#example-implementation" class="self-link"></a></h1>
<p>The most up-to-date implementation, created by Simon Brand, is available on <a href="https://github.com/TartanLlama/function_ref">GitHub/TartanLlama/function_ref</a>.</p>
<p>An older example implementation is available here on <a href="https://github.com/SuperV1234/Experiments/blob/master/function_ref.cpp">GitHub/SuperV1234/Experiments</a>.</p>
<h1 id="existing-practice"><span class="header-section-number">12</span> Existing practice<a href="#existing-practice" class="self-link"></a></h1>
<p>Many facilities similar to <code>function_ref</code> exist and are widely used in large codebases. Here are some examples:</p>
<ul>
<li><p>The <code>llvm::function_ref</code><a href="#fn2" class="footnote-ref" id="fnref2" role="doc-noteref"><sup>2</sup></a> class template is used throughout LLVM. A quick GitHub search on the LLVM organization reports hundreds of usages both in <code>llvm</code> and <code>clang</code>.<a href="#fn3" class="footnote-ref" id="fnref3" role="doc-noteref"><sup>3</sup></a></p></li>
<li><p>Facebook’s Folly libraries<a href="#fn4" class="footnote-ref" id="fnref4" role="doc-noteref"><sup>4</sup></a> provide a <code>folly::FunctionRef</code><a href="#fn5" class="footnote-ref" id="fnref5" role="doc-noteref"><sup>5</sup></a> class template. A GitHub search shows that it’s used in projects <code>proxygen</code> and <code>fbthrift</code>.<a href="#fn6" class="footnote-ref" id="fnref6" role="doc-noteref"><sup>6</sup></a></p></li>
<li><p>GNU’s popular debugger, <code>gdb</code>,<a href="#fn7" class="footnote-ref" id="fnref7" role="doc-noteref"><sup>7</sup></a> uses <code>gdb::function_view</code><a href="#fn8" class="footnote-ref" id="fnref8" role="doc-noteref"><sup>8</sup></a> throughout its code base. The documentation in the linked header file<a href="#fn9" class="footnote-ref" id="fnref9" role="doc-noteref"><sup>9</sup></a> is particularly well-written and greatly motivates the need for this facility.</p></li>
</ul>
<p>Additionally, combining results from GitHub searches <em>(excluding “<code>llvm</code>” and “<code>folly</code>”)</em> for “<code>function_ref</code>,”<a href="#fn10" class="footnote-ref" id="fnref10" role="doc-noteref"><sup>10</sup></a> “<code>function_view</code>,”<a href="#fn11" class="footnote-ref" id="fnref11" role="doc-noteref"><sup>11</sup></a> “<code>FunctionRef</code>,”<a href="#fn12" class="footnote-ref" id="fnref12" role="doc-noteref"><sup>12</sup></a> and “<code>FunctionView</code>”<a href="#fn13" class="footnote-ref" id="fnref13" role="doc-noteref"><sup>13</sup></a> roughly shows more than 2800 occurrences.</p>
<h1 id="possible-issues"><span class="header-section-number">13</span> Possible issues<a href="#possible-issues" class="self-link"></a></h1>
<p>Accepting temporaries in <code>function_ref</code>’s constructor is extremely useful in the most common use case: using it as a function parameter. E.g.</p>
<div class="sourceCode" id="cb16"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb16-1"><a href="#cb16-1"></a><span class="dt">void</span> foo<span class="op">(</span>function_ref<span class="op">&lt;</span><span class="dt">void</span><span class="op">()&gt;)</span>;</span>
<span id="cb16-2"><a href="#cb16-2"></a></span>
<span id="cb16-3"><a href="#cb16-3"></a><span class="dt">int</span> main<span class="op">()</span></span>
<span id="cb16-4"><a href="#cb16-4"></a><span class="op">{</span></span>
<span id="cb16-5"><a href="#cb16-5"></a>    foo<span class="op">([]{</span> <span class="op">})</span>;</span>
<span id="cb16-6"><a href="#cb16-6"></a><span class="op">}</span></span></code></pre></div>
<div class="inline-link">
<p><a href="https://wandbox.org/permlink/BPtbPeQtErPGj4X7"><em>(on wandbox.org)</em></a></p>
</div>
<p>The usage shown above is completely safe: the temporary closure generated by the lambda expression is guarantee to live for the entirety of the call to <code>foo</code>. Unfortunately, this also means that the following code snippet will result in <em>undefined behavior</em>:</p>
<div class="sourceCode" id="cb17"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb17-1"><a href="#cb17-1"></a><span class="dt">int</span> main<span class="op">()</span></span>
<span id="cb17-2"><a href="#cb17-2"></a><span class="op">{</span></span>
<span id="cb17-3"><a href="#cb17-3"></a>    function_ref<span class="op">&lt;</span><span class="dt">void</span><span class="op">()&gt;</span> f<span class="op">{[]{</span> <span class="op">}}</span>;</span>
<span id="cb17-4"><a href="#cb17-4"></a>    <span class="co">// ...</span></span>
<span id="cb17-5"><a href="#cb17-5"></a>    f<span class="op">()</span>; <span class="co">// undefined behavior</span></span>
<span id="cb17-6"><a href="#cb17-6"></a><span class="op">}</span></span></code></pre></div>
<div class="inline-link">
<p><a href="https://wandbox.org/permlink/cQPEX2sKjCQjgIki"><em>(on wandbox.org)</em></a></p>
</div>
<p>The above closure is a temporary whose lifetime ends after the <code>function_ref</code> constructor call. The <code>function_ref</code> will store an address to a “dead” closure - invoking it will produce undefined behavior.<a href="#fn14" class="footnote-ref" id="fnref14" role="doc-noteref"><sup>14</sup></a> As an example, <code>AddressSanitizer</code> detects an invalid memory access in this gist.<a href="#fn15" class="footnote-ref" id="fnref15" role="doc-noteref"><sup>15</sup></a> Note that this problem is not unique to <code>function_ref</code>: the recently standardized <code>std::string_view</code><a href="#fn16" class="footnote-ref" id="fnref16" role="doc-noteref"><sup>16</sup></a> has the same problem.<a href="#fn17" class="footnote-ref" id="fnref17" role="doc-noteref"><sup>17</sup></a></p>
<p>I strongly believe that accepting temporaries is a “necessary evil” for both <code>function_ref</code> and <code>std::string_view</code>, as it enables countless valid use cases. The problem of dangling references has been always present in the language - a more general solution like Herb Sutter and Neil Macintosh’s lifetime tracking<a href="#fn18" class="footnote-ref" id="fnref18" role="doc-noteref"><sup>18</sup></a> would prevent mistakes without limiting the usefulness of view/reference classes.</p>
<h1 id="bikeshedding"><span class="header-section-number">14</span> Bikeshedding<a href="#bikeshedding" class="self-link"></a></h1>
<p>The name <code>function_ref</code> is subject to bikeshedding. Here are some other potential names:</p>
<ul>
<li><p><code>function_view</code></p></li>
<li><p><code>callable_ref</code></p></li>
<li><p><code>callable_view</code></p></li>
<li><p><code>invocable_ref</code></p></li>
<li><p><code>invocable_view</code></p></li>
<li><p><code>fn_view</code></p></li>
<li><p><code>fn_ref</code></p></li>
</ul>
<h1 id="acknowledgments"><span class="header-section-number">15</span> Acknowledgments<a href="#acknowledgments" class="self-link"></a></h1>
<p>Thanks to <strong>Agustín Bergé</strong>, <strong>Dietmar Kühl</strong>, <strong>Eric Niebler</strong>, <strong>Tim van Deurzen</strong>, and <strong>Alisdair Meredith</strong> for providing very valuable feedback on earlier drafts of this proposal.</p>
<h1 id="annex-previously-open-questions"><span class="header-section-number">16</span> Annex: previously open questions<a href="#annex-previously-open-questions" class="self-link"></a></h1>
<ul>
<li><p>Why does <code>operator()</code> take <code>Args...</code> and not <code>Args&amp;&amp;...</code>?</p>
<ul>
<li>While taking <code>Args&amp;&amp;...</code> would minimize the amount of copies/moves, it would be a pessimization for small value types. Also, taking <code>Args...</code> is consistent with how <code>std::function</code> works.</li>
</ul></li>
<li><p><code>function_ref&lt;Signature&gt;</code>’s signature currently only accepts any combination of <code>const</code> and <code>noexcept</code>. Should this be extended to include <em>ref-qualifiers</em>? This would mean that <code>function_ref::operator()</code> would first cast the referenced callable to either an <em>lvalue reference</em> or <em>rvalue reference</em> (depending on <code>Signature</code>’s ref qualifiers) before invoking it. See P0045R1<a href="#fn19" class="footnote-ref" id="fnref19" role="doc-noteref"><sup>19</sup></a> and N4159<a href="#fn20" class="footnote-ref" id="fnref20" role="doc-noteref"><sup>20</sup></a>) for additional context.</p>
<ul>
<li>LEWG agreed that <code>const</code> and <code>noexcept</code> have useful cases, but we could not find enough motivation to include support for <em>ref-qualified</em> signatures. Nevertheless, this could be added as a non-breaking extension to <code>function_ref</code> in the future.</li>
</ul></li>
<li><p>Constructing a <code>std::function&lt;Signature&gt;</code> from a <code>function_ref&lt;Signature&gt;</code> is completely different from constructing a <code>std::string</code> from a <code>std::string_view</code>: the latter does actually create a copy while the former remains a reference. It may be reasonable to prevent implicit conversions from <code>function_ref</code> to <code>std::function</code> in order to avoid surprising dangerous behavior.</p>
<ul>
<li>LEWG decided to not prevent <code>std::function</code> construction from <code>std::function_ref</code> as it would special-case <code>std::function</code> and there are other utilities in the Standard Library (and outside of it) that would need a similar change (e.g. <code>std::bind</code>).</li>
</ul></li>
<li><p><code>function_ref::operator()</code> is not currently marked as <code>constexpr</code> due to implementation issues. I could not figure a way to implement a <code>constexpr</code>-friendly <code>operator()</code>. Is there any possibility it could be marked as <code>constexpr</code> to increase the usefulness of <code>function_ref</code>?</p>
<ul>
<li>We agreed that there is probably no way of currently having a <code>constexpr</code> <code>function_ref::operator()</code> and that we do not want to impose that burden on implementations.</li>
</ul></li>
<li><p>Should the <code>!f</code> precondition when constructing <code>function_ref</code> from an instance <code>f</code> of <code>std::function</code> be removed? The behavior in that case is well-defined, as <code>f</code> is guarateed to throw on invocation.</p>
<ul>
<li>LEWG decided to remove the precondition as invoking a default-constructed instance of <code>std::function</code> is well-defined.</li>
</ul></li>
<li><p>The <code>std::is_nothrow_invocable</code> constraint in <code>function_ref</code> construction/assignment for <code>noexcept</code> signatures prevents users from providing a non-<code>noexcept</code> function, even if they know that it cannot ever throw (e.g. C functions). Should this constraint be removed? Should an <code>explicit</code> constructor without the constraint be provided?</p>
<ul>
<li>LEWG agreed that the constraint should be kept and no extra constructors should be added as users can use a <code>noexcept</code> lambda to achieve the same result.</li>
</ul></li>
<li><p>Propagating <code>const</code> to <code>function_ref::operator()</code> doesn’t make sense when looking at <code>function_ref</code> as a simple “reference” class. <code>const</code> instances of <code>function_ref</code> should be able to invoke a <code>mutable</code> lambda, as the state of <code>function_ref</code> itself doesn’t change. E.g.</p>
<div class="sourceCode" id="cb18"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb18-1"><a href="#cb18-1"></a><span class="kw">auto</span> l0 <span class="op">=</span> <span class="op">[]()</span> <span class="kw">mutable</span> <span class="op">{</span> <span class="op">}</span>;</span>
<span id="cb18-2"><a href="#cb18-2"></a><span class="kw">const</span> function_ref<span class="op">&lt;</span><span class="dt">void</span><span class="op">()&gt;</span> fr<span class="op">{</span>l0<span class="op">}</span>;</span>
<span id="cb18-3"><a href="#cb18-3"></a></span>
<span id="cb18-4"><a href="#cb18-4"></a>fr<span class="op">()</span>; <span class="co">// Currently a compilation error</span></span></code></pre></div>
<p>An alternative is to only propagate <code>noexcept</code> from the signature to <code>function_ref::operator()</code>, and unconditionally <code>const</code>-qualify <code>function_ref::operator()</code>. Do we want this?</p>
<ul>
<li>LEWG agreed to mark <code>function_ref::operator()</code> <code>const</code>, unconditionally.</li>
</ul></li>
<li><p>We want to avoid double indirection when a <code>function_ref</code> instance is initialized with a <code>reference_wrapper</code>. <code>function_ref</code> could just copy the pointer stored inside the <code>reference_wrapper</code> instead of pointing to the wrapper itself. This cannot be covered by the <em>as-if</em> rule as it changes program semantics. E.g.</p>
<div class="sourceCode" id="cb19"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb19-1"><a href="#cb19-1"></a><span class="kw">auto</span> l0 <span class="op">=</span> <span class="op">[]{</span> <span class="op">}</span>;</span>
<span id="cb19-2"><a href="#cb19-2"></a><span class="kw">auto</span> l1 <span class="op">=</span> <span class="op">[]{</span> <span class="op">}</span>;</span>
<span id="cb19-3"><a href="#cb19-3"></a><span class="kw">auto</span> rw <span class="op">=</span> std<span class="op">::</span>ref<span class="op">(</span>l0<span class="op">)</span>;</span>
<span id="cb19-4"><a href="#cb19-4"></a></span>
<span id="cb19-5"><a href="#cb19-5"></a>function_ref<span class="op">&lt;</span><span class="dt">void</span><span class="op">()&gt;</span> fr<span class="op">{</span>rw<span class="op">}</span>;</span>
<span id="cb19-6"><a href="#cb19-6"></a>fr<span class="op">()</span>; <span class="co">// Invokes `l0`</span></span>
<span id="cb19-7"><a href="#cb19-7"></a></span>
<span id="cb19-8"><a href="#cb19-8"></a>rw <span class="op">=</span> l1;</span>
<span id="cb19-9"><a href="#cb19-9"></a>fr<span class="op">()</span>; <span class="co">// What is invoked?</span></span></code></pre></div>
<p>Is adding wording to handle <code>std::reference_wrapper</code> as a special case desirable?</p>
<ul>
<li>LEWG decided that special-casing <code>std::reference_wrapper</code> is undesirable.</li>
</ul></li>
<li><p>Is it possible and desirable to remove <code>function_ref</code>’s template assignment operator from <code>F&amp;&amp;</code> and rely on an implicit conversion to <code>function_ref</code> + the default copy assignment operator?</p>
<ul>
<li>LEWG deferred this question to LWG.</li>
</ul></li>
<li><p>Should <code>function_ref</code> only store a <code>void*</code> pointer for the callable object, or a <code>union</code>? In the first case, seemingly innocent usages will result in undefined behavior:</p>
<div class="sourceCode" id="cb20"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb20-1"><a href="#cb20-1"></a><span class="dt">void</span> foo<span class="op">()</span>;</span>
<span id="cb20-2"><a href="#cb20-2"></a>function_ref<span class="op">&lt;</span><span class="dt">void</span><span class="op">()&gt;</span> f<span class="op">{&amp;</span>foo<span class="op">}</span>;</span>
<span id="cb20-3"><a href="#cb20-3"></a>f<span class="op">()</span>; <span class="co">// Undefined behavior</span></span></code></pre></div>
<div class="sourceCode" id="cb21"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb21-1"><a href="#cb21-1"></a><span class="kw">struct</span> foo <span class="op">{</span> <span class="dt">void</span> bar<span class="op">()</span>; <span class="op">}</span></span>
<span id="cb21-2"><a href="#cb21-2"></a>function_ref<span class="op">&lt;</span><span class="dt">void</span><span class="op">(</span>foo<span class="op">)&gt;</span> f<span class="op">{&amp;</span>foo<span class="op">::</span>bar<span class="op">}</span>;</span>
<span id="cb21-3"><a href="#cb21-3"></a>f<span class="op">(</span>foo<span class="op">{})</span>; <span class="co">// Undefined behavior</span></span></code></pre></div>
<p>If a <code>union</code> is stored instead, the first usage could be well-formed without any extra overhead (assuming <code>sizeof(void*) == sizeof(void(*)())</code>). The second usage could also be made well-formed, but with size overhead as <code>sizeof(void(C::*)()) &gt; sizeof(void*)</code>.</p>
<p>Regardless, the exposition-only members should clearly illustrate the outcome of this decision.</p>
<p>Note that if we want the following to compile and be well-defined, a <code>void(*)()</code> would have to be stored inside <code>function_ref</code>:</p>
<div class="sourceCode" id="cb22"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb22-1"><a href="#cb22-1"></a><span class="dt">void</span> foo<span class="op">()</span>;</span>
<span id="cb22-2"><a href="#cb22-2"></a>function_ref<span class="op">&lt;</span><span class="dt">void</span><span class="op">()&gt;</span> f<span class="op">{</span>foo<span class="op">}</span>;</span>
<span id="cb22-3"><a href="#cb22-3"></a>f<span class="op">()</span>;</span></code></pre></div>
<ul>
<li>LEWG agreed that <code>function_ref</code> should fully support the <code>Callable</code> concept.</li>
</ul></li>
<li><p>Should the <code>function_ref(F&amp;&amp;)</code> deduction guide take its argument by value instead? This could simplify the wording.</p>
<ul>
<li>LEWG deferred this question to LWG.</li>
</ul></li>
</ul>
<h1 id="annex-controversial-design-decisions"><span class="header-section-number">17</span> Annex: controversial design decisions<a href="#annex-controversial-design-decisions" class="self-link"></a></h1>
<h2 id="size-of-function_ref"><span class="header-section-number">17.1</span> Size of <code>function_ref</code><a href="#size-of-function_ref" class="self-link"></a></h2>
<p><code>sizeof(function_ref)</code> is required to be maximum <code>sizeof(void*) * 2</code>. This design choice was made as it makes <code>function_ref</code> more lightweight and more likely to be passed in registers. There also has been vocal opposition to the <code>function_ref</code> having a size greater than <code>sizeof(void*) * 2</code>. The consequence of this is that construction/assignment from a pointer to member function will be UB unless the PMF itself outlives the <code>function_ref</code>. E.g.</p>
<div class="sourceCode" id="cb23"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb23-1"><a href="#cb23-1"></a>function_ref<span class="op">&lt;</span><span class="dt">void</span><span class="op">(</span><span class="kw">const</span> Foo<span class="op">&amp;)&gt;</span> fr <span class="op">=</span> <span class="op">&amp;</span>Foo<span class="op">::</span>f;</span>
<span id="cb23-2"><a href="#cb23-2"></a>    <span class="co">// Points to the temporary `&amp;Foo::f` instance.</span></span>
<span id="cb23-3"><a href="#cb23-3"></a></span>
<span id="cb23-4"><a href="#cb23-4"></a>fr<span class="op">()</span>; <span class="co">// (0)</span></span>
<span id="cb23-5"><a href="#cb23-5"></a>    <span class="co">// Undefined behavior, as the temporary `&amp;Foo::f` is dead.</span></span></code></pre></div>
<p>This was previously discussed by LEWG, and there was consensus to not make (0) well-defined as that would require <code>function_ref</code> to be bigger than two <code>void*</code> pointers.</p>
<h2 id="lifetime-of-pointers-to-function"><span class="header-section-number">17.2</span> Lifetime of pointers to function<a href="#lifetime-of-pointers-to-function" class="self-link"></a></h2>
<p>In the case of a pointer to function, even though it could be possible to avoid undefined behavior, the current design choice is to have the exact same behavior as with PMFs to avoid inconsistency. E.g.</p>
<div class="sourceCode" id="cb24"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb24-1"><a href="#cb24-1"></a><span class="dt">void</span> f<span class="op">(</span><span class="kw">const</span> Foo<span class="op">&amp;)</span>;</span>
<span id="cb24-2"><a href="#cb24-2"></a></span>
<span id="cb24-3"><a href="#cb24-3"></a>function_ref<span class="op">&lt;</span><span class="dt">void</span><span class="op">(</span><span class="kw">const</span> Foo<span class="op">&amp;)&gt;</span> fr <span class="op">=</span> <span class="op">&amp;</span>f;</span>
<span id="cb24-4"><a href="#cb24-4"></a>    <span class="co">// Points to the temporary `&amp;f` instance.</span></span>
<span id="cb24-5"><a href="#cb24-5"></a></span>
<span id="cb24-6"><a href="#cb24-6"></a>fr<span class="op">()</span>; <span class="co">// (0)</span></span>
<span id="cb24-7"><a href="#cb24-7"></a>    <span class="co">// Undefined behavior, as the temporary `&amp;f` is dead.</span></span></code></pre></div>
<p>Allowing (0) to be well-defined behavior would be possible without increasing the size of <code>function_ref</code>, but would create inconsistency with the PMF case above which would harm teachability of <code>function_ref</code> and potentially lead to bugs. This was discussed in LEWG and there was consensus to proceed with this design.</p>
<h2 id="assignment-operator"><span class="header-section-number">17.3</span> Assignment operator<a href="#assignment-operator" class="self-link"></a></h2>
<p>The main use case for <code>function_ref</code> is to be used as a function parameter, yet it exposes an assignment operator. Safe use cases for the assignment operator that do not introduce UB are rare, but some readers of this proposals have reported having valid use cases for an assignment operator.</p>
<h2 id="reference_wrapper-unwrapping"><span class="header-section-number">17.4</span> <code>reference_wrapper</code> unwrapping<a href="#reference_wrapper-unwrapping" class="self-link"></a></h2>
<p>According to a member of the committee, not unwrapping <code>std::reference_wrapper</code> when constructing/assigning-to <code>function_ref</code> causes a usability problem. There might be a performance penalty to pay due to the double indirection, and a change in semantics depending on whether or not the <code>std::reference_wrapper</code> is unwrapped. E.g.</p>
<div class="sourceCode" id="cb25"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb25-1"><a href="#cb25-1"></a><span class="kw">auto</span> l0 <span class="op">=</span> <span class="op">[]{</span> std<span class="op">::</span>cout <span class="op">&lt;&lt;</span> <span class="st">&quot;l0</span><span class="sc">\n</span><span class="st">&quot;</span>; <span class="op">}</span>;</span>
<span id="cb25-2"><a href="#cb25-2"></a><span class="kw">auto</span> l1 <span class="op">=</span> <span class="op">[]{</span> std<span class="op">::</span>cout <span class="op">&lt;&lt;</span> <span class="st">&quot;l1</span><span class="sc">\n</span><span class="st">&quot;</span>; <span class="op">}</span>;</span>
<span id="cb25-3"><a href="#cb25-3"></a></span>
<span id="cb25-4"><a href="#cb25-4"></a>std<span class="op">::</span>reference_wrapper rw<span class="op">{</span>std<span class="op">::</span>ref<span class="op">(</span>l0<span class="op">)}</span>;</span>
<span id="cb25-5"><a href="#cb25-5"></a>function_ref<span class="op">&lt;</span><span class="dt">void</span><span class="op">()&gt;</span> fr<span class="op">(</span>rw<span class="op">)</span>; <span class="co">// Points to `rw` itself.</span></span>
<span id="cb25-6"><a href="#cb25-6"></a></span>
<span id="cb25-7"><a href="#cb25-7"></a>fr<span class="op">()</span>; <span class="co">// Prints out `l0`.</span></span>
<span id="cb25-8"><a href="#cb25-8"></a></span>
<span id="cb25-9"><a href="#cb25-9"></a>rw <span class="op">=</span> l1;</span>
<span id="cb25-10"><a href="#cb25-10"></a></span>
<span id="cb25-11"><a href="#cb25-11"></a>fr<span class="op">()</span>; <span class="co">// Prints out `l1`.</span></span></code></pre></div>
<p>This problem was discussed in LEWG at the Rapperswil meeting, and there was unanimous dissent to special-casing <code>std::reference_wrapper</code>.</p>
<h1 id="annex-existing-practice-survey"><span class="header-section-number">18</span> Annex: existing practice survey<a href="#annex-existing-practice-survey" class="self-link"></a></h1>
<p>The following types have been surveyed: <code>folly::FunctionRef</code>, <code>llvm::function_ref</code>, and <code>gdb::function_view</code> to check how often they were used and in which circumstances. Below are the results:</p>
<ul>
<li><code>folly::FunctionRef</code>
<ul>
<li>https://github.com/facebook/folly/blob/master/folly/Function.h</li>
<li>Stores <code>void*</code> + pointer to non-member function</li>
<li>Implicitly generated assignment (supported)</li>
<li>No special treatment of <code>std::reference_wrapper</code></li>
<li>15~, most are function parameters</li>
<li>Only 1~ non-parameter use
<ul>
<li>Used as a local variable, constructed via ternary operator:
<ul>
<li>Might be UB: https://github.com/facebook/folly/issues/1190</li>
</ul></li>
</ul></li>
</ul></li>
<li><code>llvm::function_ref</code>
<ul>
<li>https://github.com/llvm-mirror/llvm/blob/master/include/llvm/ADT/STLExtras.h</li>
<li>Stores <code>void*</code> + pointer to non-member function</li>
<li>Implicitly generated assignment (supported)</li>
<li>No special treatment of <code>std::reference_wrapper</code></li>
<li>200~ uses, most are function parameters</li>
<li>Only 8~ non-parameter uses
<ul>
<li>Used as a data member - initialized on construction and never rebound:
<ul>
<li>https://github.com/llvm-mirror/lldb/blob/3f6f84dc70a087fb6976049548d2711a5851a58d/source/Symbol/PostfixExpression.cpp</li>
<li>https://github.com/llvm-mirror/llvm/blob/6b547686c5410b7528212e898fe30fc7ee7a70a3/include/llvm/XRay/FDRTraceExpander.h</li>
<li>https://github.com/llvm-mirror/llvm/blob/6b547686c5410b7528212e898fe30fc7ee7a70a3/lib/Analysis/ScalarEvolutionNormalization.cpp(with comment about lifetimes)</li>
<li>https://github.com/llvm-mirror/llvm/blob/8964612be0720857ec1d2f057bdecc01c7da5441/include/llvm/Transforms/Utils/SimplifyLibCalls.h</li>
<li>https://github.com/llvm-mirror/llvm/blob/09497f0d9e6f2794245347cd7228d88b2fd94de3/lib/CodeGen/AsmPrinter/AccelTable.cpp</li>
<li>https://github.com/llvm-mirror/llvm/blob/09497f0d9e6f2794245347cd7228d88b2fd94de3/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp</li>
</ul></li>
<li>Used as a local variable, assigned to an lvalue in the scope:
<ul>
<li>https://github.com/llvm-mirror/clang/blob/ce7674d7be842d4863b410ce1dfd89416256e9c1/lib/Parse/ParseDecl.cpp</li>
</ul></li>
<li>Created on the stack and passed to a function by address:
<ul>
<li>https://github.com/llvm-mirror/llvm/blob/c3f211d97bb0203fefdf5624fc672192b821a8f0/lib/CodeGen/MachineBlockPlacement.cpp</li>
</ul></li>
</ul></li>
</ul></li>
<li><code>gdb::function_view</code>
<ul>
<li>https://github.com/bminor/binutils-gdb/blob/eb6ad40f244ea6dedca1440b0ce3d89c1ecdac0c/gdb/gdbsupport/function-view.h</li>
<li>Stores a union of <code>void*</code> and <code>void(*)()</code></li>
<li>Defaulted assignment operator (supported)</li>
<li>No special treatment of <code>std::reference_wrapper</code></li>
<li>30~ uses, all are function parameters</li>
</ul></li>
</ul>
<p>Conclusions:</p>
<ul>
<li>Most of the uses are for function parameters, but there are some valid use cases for storing <code>function_ref</code> or using assignment;</li>
<li>2 out of 3 implementations only store a <code>void*</code> plus function pointer, making function pointers UB as in P0792;</li>
<li>No special treatment of any reference_wrapper-like class;</li>
<li>Every implementation supports assignment (either implicitly generated or <code>=default</code>).</li>
</ul>
<h1 id="references"><span class="header-section-number">19</span> References<a href="#references" class="self-link"></a></h1>
<p><small></p>
<p></small></p>
<section class="footnotes" role="doc-endnotes">
<hr />
<ol>
<li id="fn1" role="doc-endnote"><p><a href="https://vittorioromeo.info/index/blog/passing_functions_to_functions.html#benchmark---generated-assembly" class="uri">https://vittorioromeo.info/index/blog/passing_functions_to_functions.html#benchmark---generated-assembly</a><a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn2" role="doc-endnote"><p><a href="http://llvm.org/doxygen/classllvm_1_1function__ref_3_01Ret_07Params_8_8_8_08_4.html" class="uri">http://llvm.org/doxygen/classllvm_1_1function__ref_3_01Ret_07Params_8_8_8_08_4.html</a><a href="#fnref2" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn3" role="doc-endnote"><p><a href="https://github.com/search?q=org%3Allvm-mirror+function_ref&amp;type=Code" class="uri">https://github.com/search?q=org%3Allvm-mirror+function_ref&amp;type=Code</a><a href="#fnref3" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn4" role="doc-endnote"><p><a href="https://github.com/facebook/folly" class="uri">https://github.com/facebook/folly</a><a href="#fnref4" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn5" role="doc-endnote"><p><a href="https://github.com/facebook/folly/blob/master/folly/Function.h#L743-L824" class="uri">https://github.com/facebook/folly/blob/master/folly/Function.h#L743-L824</a><a href="#fnref5" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn6" role="doc-endnote"><p><a href="https://github.com/search?q=org%3Afacebook+FunctionRef&amp;type=Code" class="uri">https://github.com/search?q=org%3Afacebook+FunctionRef&amp;type=Code</a><a href="#fnref6" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn7" role="doc-endnote"><p><a href="https://www.gnu.org/software/gdb/" class="uri">https://www.gnu.org/software/gdb/</a><a href="#fnref7" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn8" role="doc-endnote"><p><a href="https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=blob;f=gdb/common/function-view.h" class="uri">https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=blob;f=gdb/common/function-view.h</a><a href="#fnref8" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn9" role="doc-endnote"><p><a href="https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=blob;f=gdb/common/function-view.h" class="uri">https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=blob;f=gdb/common/function-view.h</a><a href="#fnref9" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn10" role="doc-endnote"><p><a href="https://github.com/search?utf8=%E2%9C%93&amp;q=function_ref+AND+NOT+llvm+AND+NOT+folly+language%3AC%2B%2B&amp;type=Code" class="uri">https://github.com/search?utf8=%E2%9C%93&amp;q=function_ref+AND+NOT+llvm+AND+NOT+folly+language%3AC%2B%2B&amp;type=Code</a><a href="#fnref10" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn11" role="doc-endnote"><p><a href="https://github.com/search?utf8=%E2%9C%93&amp;q=function_view+AND+NOT+llvm+AND+NOT+folly+language%3AC%2B%2B&amp;type=Code" class="uri">https://github.com/search?utf8=%E2%9C%93&amp;q=function_view+AND+NOT+llvm+AND+NOT+folly+language%3AC%2B%2B&amp;type=Code</a><a href="#fnref11" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn12" role="doc-endnote"><p><a href="https://github.com/search?utf8=%E2%9C%93&amp;q=functionref+AND+NOT+llvm+AND+NOT+folly+language%3AC%2B%2B&amp;type=Code" class="uri">https://github.com/search?utf8=%E2%9C%93&amp;q=functionref+AND+NOT+llvm+AND+NOT+folly+language%3AC%2B%2B&amp;type=Code</a><a href="#fnref12" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn13" role="doc-endnote"><p><a href="https://github.com/search?utf8=%E2%9C%93&amp;q=functionview+AND+NOT+llvm+AND+NOT+folly+language%3AC%2B%2B&amp;type=Code" class="uri">https://github.com/search?utf8=%E2%9C%93&amp;q=functionview+AND+NOT+llvm+AND+NOT+folly+language%3AC%2B%2B&amp;type=Code</a><a href="#fnref13" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn14" role="doc-endnote"><p><a href="http://foonathan.net/blog/2017/01/20/function-ref-implementation.html" class="uri">http://foonathan.net/blog/2017/01/20/function-ref-implementation.html</a><a href="#fnref14" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn15" role="doc-endnote"><p><a href="https://gist.github.com/SuperV1234/a41eb1c825bfbb43f595b13bd4ea99c3" class="uri">https://gist.github.com/SuperV1234/a41eb1c825bfbb43f595b13bd4ea99c3</a><a href="#fnref15" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn16" role="doc-endnote"><p><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3762.html" class="uri">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3762.html</a><a href="#fnref16" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn17" role="doc-endnote"><p><a href="http://foonathan.net/blog/2017/03/22/string_view-temporary.html" class="uri">http://foonathan.net/blog/2017/03/22/string_view-temporary.html</a><a href="#fnref17" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn18" role="doc-endnote"><p><a href="https://github.com/isocpp/CppCoreGuidelines/blob/master/docs/Lifetimes%20I%20and%20II%20-%20v0.9.1.pdf" class="uri">https://github.com/isocpp/CppCoreGuidelines/blob/master/docs/Lifetimes%20I%20and%20II%20-%20v0.9.1.pdf</a><a href="#fnref18" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn19" role="doc-endnote"><p><a href="http://wg21.link/p0045r1" class="uri">http://wg21.link/p0045r1</a><a href="#fnref19" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn20" role="doc-endnote"><p><a href="http://wg21.link/N4159" class="uri">http://wg21.link/N4159</a><a href="#fnref20" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section> 
        </div>
    </div>
</body>

</html>