<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang xml:lang>
<head>
  <meta charset="utf-8" />
  <meta name="generator" content="pandoc" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
  <title>Untitled</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>
a.sourceLine { display: inline-block; line-height: 1.25; }
a.sourceLine { pointer-events: none; color: inherit; text-decoration: inherit; }
a.sourceLine: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; }
a.sourceLine { text-indent: -1em; padding-left: 1em; }
}
pre.numberSource a.sourceLine
  { position: relative; left: -4em; }
pre.numberSource a.sourceLine::before
  { content: attr(title);
    position: relative; left: -1em; text-align: right; vertical-align: baseline;
    border: none; pointer-events: all; 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
  {  }
@media screen {
a.sourceLine::before { text-decoration: underline; }
}
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code span.at { color: #7d9029; } /* Attribute */
code span.bn { color: #40a070; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code span.ch { color: #4070a0; } /* Char */
code span.cn { color: #880000; } /* Constant */
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
code span.dt { color: #902000; } /* DataType */
code span.dv { color: #40a070; } /* DecVal */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #40a070; } /* Float */
code span.fu { color: #06287e; } /* Function */
code span.im { } /* Import */
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
code span.op { color: #666666; } /* Operator */
code span.ot { color: #007020; } /* Other */
code span.pp { color: #bc7a00; } /* Preprocessor */
code span.sc { color: #4070a0; } /* SpecialChar */
code span.ss { color: #bb6688; } /* SpecialString */
code span.st { color: #4070a0; } /* String */
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
  </style>
  <style type="text/css">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}}</style>
  <!--[if lt IE 9]>
    <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
  <![endif]-->
</head>
<body>
<table>
<tbody>
<tr class="odd">
<td>Document number</td>
<td>P0792R4</td>
</tr>
<tr class="even">
<td>Date</td>
<td>2018-10-07</td>
</tr>
<tr class="odd">
<td>Reply-to</td>
<td>Vittorio Romeo &lt;<a href="mailto:vittorio.romeo@outlook.com" class="email">vittorio.romeo@outlook.com</a>&gt;</td>
</tr>
<tr class="even">
<td>Audience</td>
<td>Library Working Group (LWG)</td>
</tr>
<tr class="odd">
<td>Project</td>
<td>ISO JTC1/SC22/WG21: Programming Language C++</td>
</tr>
</tbody>
</table>
<h1 id="function_ref-a-non-owning-reference-to-a-callable"><code>function_ref</code>: a non-owning reference to a <code>Callable</code></h1>
<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>
<h2 id="abstract">Abstract</h2>
<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>
<h2 id="changelog-and-polls">Changelog and polls</h2>
<h3 id="from-r3-to-r4">From R3 to R4</h3>
<h4 id="changes">Changes</h4>
<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>
<h3 id="from-r2-to-r3">From R2 to R3</h3>
<h4 id="changes-1">Changes</h4>
<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>
<h4 id="polls">Polls</h4>
<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>
<h3 id="from-r1-to-r2">From R1 to R2</h3>
<h4 id="changes-2">Changes</h4>
<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>
<h4 id="polls-1">Polls</h4>
<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>
<h3 id="from-r0-to-r1">From R0 to R1</h3>
<h4 id="changes-3">Changes</h4>
<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>
<h4 id="semantics-pointer-versus-reference">Semantics: pointer versus reference</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"><code>target</code> and <code>target_type</code></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>
<h2 id="table-of-contents">Table of contents</h2>
<ul>
<li><a href="#functionref-a-non-owning-reference-to-a-callable"><code>function_ref</code>: a non-owning reference to a <code>Callable</code></a>
<ul>
<li><a href="#abstract">Abstract</a></li>
<li><a href="#changelog-and-polls">Changelog and polls</a>
<ul>
<li><a href="#from-r2-to-r3">From R2 to R3</a>
<ul>
<li><a href="#changes">Changes</a></li>
<li><a href="#polls">Polls</a></li>
</ul></li>
<li><a href="#from-r1-to-r2">From R1 to R2</a>
<ul>
<li><a href="#changes-1">Changes</a></li>
<li><a href="#polls-1">Polls</a></li>
</ul></li>
<li><a href="#from-r0-to-r1">From R0 to R1</a>
<ul>
<li><a href="#changes-2">Changes</a></li>
<li><a href="#semantics-pointer-versus-reference">Semantics: pointer versus reference</a></li>
<li><a href="#target-and-targettype"><code>target</code> and <code>target_type</code></a></li>
</ul></li>
</ul></li>
<li><a href="#table-of-contents">Table of contents</a></li>
<li><a href="#overview">Overview</a></li>
<li><a href="#motivating-example">Motivating example</a></li>
<li><a href="#impact-on-the-standard">Impact on the Standard</a></li>
<li><a href="#alternatives">Alternatives</a></li>
<li><a href="#changes-to-functional-header">Changes to <code>&lt;functional&gt;</code> header</a></li>
<li><a href="#class-synopsis">Class synopsis</a></li>
<li><a href="#specification">Specification</a></li>
<li><a href="#feature-test-macro">Feature test macro</a></li>
<li><a href="#example-implementation">Example implementation</a></li>
<li><a href="#existing-practice">Existing practice</a></li>
<li><a href="#possible-issues">Possible issues</a></li>
<li><a href="#bikeshedding">Bikeshedding</a></li>
<li><a href="#acknowledgments">Acknowledgments</a></li>
<li><a href="#annex-previously-open-questions">Annex: previously open questions</a></li>
<li><a href="#references">References</a></li>
</ul></li>
</ul>
<h2 id="overview">Overview</h2>
<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>
<h2 id="motivating-example">Motivating example</h2>
<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"><a class="sourceLine" id="cb1-1" title="1"><span class="kw">struct</span> payload { <span class="co">/* ... */</span> };</a>
<a class="sourceLine" id="cb1-2" title="2"></a>
<a class="sourceLine" id="cb1-3" title="3"><span class="co">// Repeatedly invokes `action` up to `times` repetitions.</span></a>
<a class="sourceLine" id="cb1-4" title="4"><span class="co">// Immediately returns if `action` returns a valid `payload`.</span></a>
<a class="sourceLine" id="cb1-5" title="5"><span class="co">// Returns `std::nullopt` otherwise.</span></a>
<a class="sourceLine" id="cb1-6" title="6"><span class="bu">std::</span>optional&lt;payload&gt; retry(<span class="bu">std::</span>size_t times, <span class="co">/* ????? */</span> action);</a></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"><a class="sourceLine" id="cb2-1" title="1"><span class="bu">std::</span>optional&lt;payload&gt; retry(<span class="bu">std::</span>size_t times,</a>
<a class="sourceLine" id="cb2-2" title="2">                             <span class="bu">std::</span>optional&lt;payload&gt;(*action)())</a>
<a class="sourceLine" id="cb2-3" title="3">{</a>
<a class="sourceLine" id="cb2-4" title="4">    <span class="co">/* ... */</span></a>
<a class="sourceLine" id="cb2-5" title="5">}</a></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"><a class="sourceLine" id="cb3-1" title="1"><span class="kw">template</span> &lt;<span class="kw">typename</span> F&gt;</a>
<a class="sourceLine" id="cb3-2" title="2"><span class="kw">auto</span> retry(<span class="bu">std::</span>size_t times, F&amp;&amp; action)</a>
<a class="sourceLine" id="cb3-3" title="3">    -&gt; <span class="bu">std::</span>enable_if_t&lt;<span class="bu">std::</span>is_invocable_r_v&lt;<span class="bu">std::</span>optional&lt;payload&gt;, F&amp;&amp;&gt;,</a>
<a class="sourceLine" id="cb3-4" title="4">                        <span class="bu">std::</span>optional&lt;payload&gt;&gt;</a>
<a class="sourceLine" id="cb3-5" title="5">{</a>
<a class="sourceLine" id="cb3-6" title="6">    <span class="co">/* ... */</span></a>
<a class="sourceLine" id="cb3-7" title="7">}</a></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"><a class="sourceLine" id="cb4-1" title="1"><span class="bu">std::</span>optional&lt;payload&gt; retry(<span class="bu">std::</span>size_t times,</a>
<a class="sourceLine" id="cb4-2" title="2">                             <span class="bu">std::</span>function&lt;<span class="bu">std::</span>optional&lt;payload&gt;()&gt; action)</a>
<a class="sourceLine" id="cb4-3" title="3">{</a>
<a class="sourceLine" id="cb4-4" title="4">    <span class="co">/* ... */</span></a>
<a class="sourceLine" id="cb4-5" title="5">}</a></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"><a class="sourceLine" id="cb5-1" title="1"><span class="bu">std::</span>optional&lt;payload&gt; retry(<span class="bu">std::</span>size_t times,</a>
<a class="sourceLine" id="cb5-2" title="2">                             function_ref&lt;<span class="bu">std::</span>optional&lt;payload&gt;()&gt; action)</a>
<a class="sourceLine" id="cb5-3" title="3">{</a>
<a class="sourceLine" id="cb5-4" title="4">    <span class="co">/* ... */</span></a>
<a class="sourceLine" id="cb5-5" title="5">}</a></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>
<h2 id="impact-on-the-standard">Impact on the Standard</h2>
<p>This proposal is a pure library extension. It does not require changes to any existing part of the Standard.</p>
<h2 id="alternatives">Alternatives</h2>
<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"><a class="sourceLine" id="cb6-1" title="1"><span class="dt">void</span> foo(<span class="bu">std::</span>function&lt;<span class="dt">void</span>()&gt; f);</a>
<a class="sourceLine" id="cb6-2" title="2"><span class="co">// `f` could be referring to an existing Callable, or could own one.</span></a>
<a class="sourceLine" id="cb6-3" title="3"></a>
<a class="sourceLine" id="cb6-4" title="4"><span class="dt">void</span> bar(function_ref&lt;<span class="dt">void</span>()&gt; f);</a>
<a class="sourceLine" id="cb6-5" title="5"><span class="co">// `f` unambiguously is a non-owning reference to an existing Callable.</span></a></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"><a class="sourceLine" id="cb7-1" title="1"><span class="dt">void</span> foo(<span class="bu">std::</span>function&lt;<span class="dt">void</span>()&gt; f);</a>
<a class="sourceLine" id="cb7-2" title="2"></a>
<a class="sourceLine" id="cb7-3" title="3"><span class="dt">int</span> main()</a>
<a class="sourceLine" id="cb7-4" title="4">{</a>
<a class="sourceLine" id="cb7-5" title="5">    <span class="dt">int</span> x = <span class="dv">0</span>;</a>
<a class="sourceLine" id="cb7-6" title="6">    foo(<span class="bu">std::</span>ref([&amp;x]{ ++x; }); <span class="co">// does not compile</span></a>
<a class="sourceLine" id="cb7-7" title="7">}</a></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>
<h2 id="changes-to-functional-header">Changes to <code>&lt;functional&gt;</code> header</h2>
<p>Add the following to <code>[functional.syn]</code>:</p>
<blockquote>
<div class="sourceCode" id="cb8"><pre class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb8-1" title="1"><span class="kw">namespace</span> std</a>
<a class="sourceLine" id="cb8-2" title="2">{</a>
<a class="sourceLine" id="cb8-3" title="3">    <span class="co">// ...</span></a>
<a class="sourceLine" id="cb8-4" title="4"></a>
<a class="sourceLine" id="cb8-5" title="5">    <span class="kw">template</span> &lt;<span class="kw">typename</span> Signature&gt; <span class="kw">class</span> function_ref;</a>
<a class="sourceLine" id="cb8-6" title="6"></a>
<a class="sourceLine" id="cb8-7" title="7">    <span class="kw">template</span> &lt;<span class="kw">typename</span> Signature&gt;</a>
<a class="sourceLine" id="cb8-8" title="8">    <span class="dt">void</span> swap(function_ref&lt;Signature&gt;&amp; lhs, function_ref&lt;Signature&gt;&amp; rhs) <span class="kw">noexcept</span>;</a>
<a class="sourceLine" id="cb8-9" title="9"></a>
<a class="sourceLine" id="cb8-10" title="10">    <span class="co">// ...</span></a>
<a class="sourceLine" id="cb8-11" title="11">}</a></code></pre></div>
</blockquote>
<h2 id="class-synopsis">Class synopsis</h2>
<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"><a class="sourceLine" id="cb9-1" title="1"><span class="kw">namespace</span> std</a>
<a class="sourceLine" id="cb9-2" title="2">{</a>
<a class="sourceLine" id="cb9-3" title="3">    <span class="kw">template</span> &lt;<span class="kw">typename</span> Signature&gt;</a>
<a class="sourceLine" id="cb9-4" title="4">    <span class="kw">class</span> function_ref</a>
<a class="sourceLine" id="cb9-5" title="5">    {</a>
<a class="sourceLine" id="cb9-6" title="6">        <span class="dt">void</span>* erased_object; <span class="co">// exposition only</span></a>
<a class="sourceLine" id="cb9-7" title="7"></a>
<a class="sourceLine" id="cb9-8" title="8">        R(*erased_function)(Args...); <span class="co">// exposition only</span></a>
<a class="sourceLine" id="cb9-9" title="9">        <span class="co">// `R`, and `Args...` are the return type, and the parameter-type-list,</span></a>
<a class="sourceLine" id="cb9-10" title="10">        <span class="co">// of the function type `Signature`, respectively.</span></a>
<a class="sourceLine" id="cb9-11" title="11"></a>
<a class="sourceLine" id="cb9-12" title="12">    <span class="kw">public</span>:</a>
<a class="sourceLine" id="cb9-13" title="13">        function_ref(<span class="at">const</span> function_ref&amp;) <span class="kw">noexcept</span> = <span class="cf">default</span>;</a>
<a class="sourceLine" id="cb9-14" title="14"></a>
<a class="sourceLine" id="cb9-15" title="15">        <span class="kw">template</span> &lt;<span class="kw">typename</span> F&gt;</a>
<a class="sourceLine" id="cb9-16" title="16">        function_ref(F&amp;&amp;);</a>
<a class="sourceLine" id="cb9-17" title="17"></a>
<a class="sourceLine" id="cb9-18" title="18">        function_ref&amp; <span class="kw">operator</span>=(<span class="at">const</span> function_ref&amp;) <span class="kw">noexcept</span> = <span class="cf">default</span>;</a>
<a class="sourceLine" id="cb9-19" title="19"></a>
<a class="sourceLine" id="cb9-20" title="20">        <span class="kw">template</span> &lt;<span class="kw">typename</span> F&gt;</a>
<a class="sourceLine" id="cb9-21" title="21">        function_ref&amp; <span class="kw">operator</span>=(F&amp;&amp;);</a>
<a class="sourceLine" id="cb9-22" title="22"></a>
<a class="sourceLine" id="cb9-23" title="23">        <span class="dt">void</span> swap(function_ref&amp;) <span class="kw">noexcept</span>;</a>
<a class="sourceLine" id="cb9-24" title="24"></a>
<a class="sourceLine" id="cb9-25" title="25">        R <span class="kw">operator</span>()(Args...) <span class="at">const</span> <span class="kw">noexcept</span>(see below);</a>
<a class="sourceLine" id="cb9-26" title="26">        <span class="co">// `R` and `Args...` are the return type and the parameter-type-list</span></a>
<a class="sourceLine" id="cb9-27" title="27">        <span class="co">// of the function type `Signature`, respectively.</span></a>
<a class="sourceLine" id="cb9-28" title="28">    };</a>
<a class="sourceLine" id="cb9-29" title="29"></a>
<a class="sourceLine" id="cb9-30" title="30">    <span class="kw">template</span> &lt;<span class="kw">typename</span> Signature&gt;</a>
<a class="sourceLine" id="cb9-31" title="31">    <span class="dt">void</span> swap(function_ref&lt;Signature&gt;&amp;, function_ref&lt;Signature&gt;&amp;) <span class="kw">noexcept</span>;</a>
<a class="sourceLine" id="cb9-32" title="32"></a>
<a class="sourceLine" id="cb9-33" title="33">    <span class="kw">template</span> &lt;<span class="kw">typename</span> R, <span class="kw">typename</span>... Args&gt;</a>
<a class="sourceLine" id="cb9-34" title="34">    function_ref(R (*)(Args...)) -&gt; function_ref&lt;R(Args...)&gt;;</a>
<a class="sourceLine" id="cb9-35" title="35"></a>
<a class="sourceLine" id="cb9-36" title="36">    <span class="kw">template</span> &lt;<span class="kw">typename</span> R, <span class="kw">typename</span>... Args&gt;</a>
<a class="sourceLine" id="cb9-37" title="37">    function_ref(R (*)(Args...) <span class="kw">noexcept</span>) -&gt; function_ref&lt;R(Args...) <span class="kw">noexcept</span>&gt;;</a>
<a class="sourceLine" id="cb9-38" title="38"></a>
<a class="sourceLine" id="cb9-39" title="39">    <span class="kw">template</span> &lt;<span class="kw">typename</span> F&gt;</a>
<a class="sourceLine" id="cb9-40" title="40">    function_ref(F) -&gt; function_ref&lt;see below&gt;;</a>
<a class="sourceLine" id="cb9-41" title="41">}</a></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>
<h2 id="specification">Specification</h2>
<div class="sourceCode" id="cb10"><pre class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb10-1" title="1"><span class="kw">template</span> &lt;<span class="kw">typename</span> F&gt;</a>
<a class="sourceLine" id="cb10-2" title="2">function_ref(F&amp;&amp; f);</a></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 <code>noexcept</code> specifier: <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"><a class="sourceLine" id="cb11-1" title="1"><span class="kw">template</span> &lt;<span class="kw">typename</span> F&gt;</a>
<a class="sourceLine" id="cb11-2" title="2">function_ref&amp; <span class="kw">operator</span>=(F&amp;&amp;);</a></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 <code>noexcept</code> specifier: <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"><a class="sourceLine" id="cb12-1" title="1"><span class="dt">void</span> swap(function_ref&amp; rhs) <span class="kw">noexcept</span>;</a></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"><a class="sourceLine" id="cb13-1" title="1">R <span class="kw">operator</span>()(Args... xs) qualifiers <span class="kw">noexcept</span>(see below);</a></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"><a class="sourceLine" id="cb14-1" title="1"><span class="kw">template</span> &lt;<span class="kw">typename</span> F&gt;</a>
<a class="sourceLine" id="cb14-2" title="2">function_ref(F) -&gt; function_ref&lt;see below&gt;;</a></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"><a class="sourceLine" id="cb15-1" title="1"><span class="kw">template</span> &lt;<span class="kw">typename</span> Signature&gt;</a>
<a class="sourceLine" id="cb15-2" title="2"><span class="dt">void</span> swap(function_ref&lt;Signature&gt;&amp; lhs, function_ref&lt;Signature&gt;&amp; rhs) <span class="kw">noexcept</span>;</a></code></pre></div>
<ul>
<li><em>Effects:</em> Equivalent to <code>lhs.swap(rhs)</code>.</li>
</ul>
<p><br></p>
<h2 id="feature-test-macro">Feature test macro</h2>
<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>Macro name</th>
<th>Value</th>
<th>Headers</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>
<h2 id="example-implementation">Example implementation</h2>
<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>
<h2 id="existing-practice">Existing practice</h2>
<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>
<h2 id="possible-issues">Possible issues</h2>
<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"><a class="sourceLine" id="cb16-1" title="1"><span class="dt">void</span> foo(function_ref&lt;<span class="dt">void</span>()&gt;);</a>
<a class="sourceLine" id="cb16-2" title="2"></a>
<a class="sourceLine" id="cb16-3" title="3"><span class="dt">int</span> main()</a>
<a class="sourceLine" id="cb16-4" title="4">{</a>
<a class="sourceLine" id="cb16-5" title="5">    foo([]{ });</a>
<a class="sourceLine" id="cb16-6" title="6">}</a></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"><a class="sourceLine" id="cb17-1" title="1"><span class="dt">int</span> main()</a>
<a class="sourceLine" id="cb17-2" title="2">{</a>
<a class="sourceLine" id="cb17-3" title="3">    function_ref&lt;<span class="dt">void</span>()&gt; f{[]{ }};</a>
<a class="sourceLine" id="cb17-4" title="4">    <span class="co">// ...</span></a>
<a class="sourceLine" id="cb17-5" title="5">    f(); <span class="co">// undefined behavior</span></a>
<a class="sourceLine" id="cb17-6" title="6">}</a></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>
<h2 id="bikeshedding">Bikeshedding</h2>
<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>
<h2 id="acknowledgments">Acknowledgments</h2>
<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>
<h2 id="annex-previously-open-questions">Annex: previously open questions</h2>
<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"><a class="sourceLine" id="cb18-1" title="1"><span class="kw">auto</span> l0 = []() <span class="at">mutable</span> { };</a>
<a class="sourceLine" id="cb18-2" title="2"><span class="at">const</span> function_ref&lt;<span class="dt">void</span>()&gt; fr{l0};</a>
<a class="sourceLine" id="cb18-3" title="3"></a>
<a class="sourceLine" id="cb18-4" title="4">fr(); <span class="co">// Currently a compilation error</span></a></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"><a class="sourceLine" id="cb19-1" title="1"><span class="kw">auto</span> l0 = []{ };</a>
<a class="sourceLine" id="cb19-2" title="2"><span class="kw">auto</span> l1 = []{ };</a>
<a class="sourceLine" id="cb19-3" title="3"><span class="kw">auto</span> rw = <span class="bu">std::</span>ref(l0);</a>
<a class="sourceLine" id="cb19-4" title="4"></a>
<a class="sourceLine" id="cb19-5" title="5">function_ref&lt;<span class="dt">void</span>()&gt; fr{rw};</a>
<a class="sourceLine" id="cb19-6" title="6">fr(); <span class="co">// Invokes `l0`</span></a>
<a class="sourceLine" id="cb19-7" title="7"></a>
<a class="sourceLine" id="cb19-8" title="8">rw = l1;</a>
<a class="sourceLine" id="cb19-9" title="9">fr(); <span class="co">// What is invoked?</span></a></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"><a class="sourceLine" id="cb20-1" title="1"><span class="dt">void</span> foo();</a>
<a class="sourceLine" id="cb20-2" title="2">function_ref&lt;<span class="dt">void</span>()&gt; f{&amp;foo};</a>
<a class="sourceLine" id="cb20-3" title="3">f(); <span class="co">// Undefined behavior</span></a></code></pre></div>
<div class="sourceCode" id="cb21"><pre class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb21-1" title="1"><span class="kw">struct</span> foo { <span class="dt">void</span> bar(); }</a>
<a class="sourceLine" id="cb21-2" title="2">function_ref&lt;<span class="dt">void</span>(foo)&gt; f{&amp;foo::bar};</a>
<a class="sourceLine" id="cb21-3" title="3">f(foo{}); <span class="co">// Undefined behavior</span></a></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"><a class="sourceLine" id="cb22-1" title="1"><span class="dt">void</span> foo();</a>
<a class="sourceLine" id="cb22-2" title="2">function_ref&lt;<span class="dt">void</span>()&gt; f{foo};</a>
<a class="sourceLine" id="cb22-3" title="3">f();</a></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>
<h2 id="references">References</h2>
<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>
</body>
</html>
