<!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 type="text/css">
      code{white-space: pre-wrap;}
      span.smallcaps{font-variant: small-caps;}
      div.line-block{white-space: pre-line;}
      div.column{display: inline-block; vertical-align: top; width: 50%;}
  </style>
  <style type="text/css">
a.sourceLine { display: inline-block; min-height: 1.25em; }
a.sourceLine { pointer-events: none; color: inherit; text-decoration: inherit; }
.sourceCode { overflow: visible; }
code.sourceCode { white-space: pre; }
@media print {
code.sourceCode { white-space: pre-wrap; }
a.sourceLine { text-indent: -1em; padding-left: 1em; }
}
pre.numberSource a.sourceLine
  { position: relative; }
pre.numberSource a.sourceLine::before
  { content: attr(data-line-number);
    position: absolute; left: -5em; text-align: right; vertical-align: baseline;
    border: none; pointer-events: all;
    -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; }
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; color: #aaaaaa;  padding-left: 4px; }
@media screen {
a.sourceLine::before { text-decoration: underline; color: initial; }
}
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
code span.dt { color: #902000; } /* DataType */
code span.dv { color: #40a070; } /* DecVal */
code span.bn { color: #40a070; } /* BaseN */
code span.fl { color: #40a070; } /* Float */
code span.ch { color: #4070a0; } /* Char */
code span.st { color: #4070a0; } /* String */
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
code span.ot { color: #007020; } /* Other */
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
code span.fu { color: #06287e; } /* Function */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
code span.cn { color: #880000; } /* Constant */
code span.sc { color: #4070a0; } /* SpecialChar */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.ss { color: #bb6688; } /* SpecialString */
code span.im { } /* Import */
code span.va { color: #19177c; } /* Variable */
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code span.op { color: #666666; } /* Operator */
code span.bu { } /* BuiltIn */
code span.ex { } /* Extension */
code span.pp { color: #bc7a00; } /* Preprocessor */
code span.at { color: #7d9029; } /* Attribute */
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
  </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>P0792R1</td>
</tr>
<tr class="even">
<td>Date</td>
<td>2017-11-26</td>
</tr>
<tr class="odd">
<td>Reply-to</td>
<td>Vittorio Romeo &lt;<a href="mailto:vittorio.romeo@outlook.com">vittorio.romeo@outlook.com</a>&gt;</td>
</tr>
<tr class="even">
<td>Audience</td>
<td>Library Evolution Working Group</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-p0792r0-to-p0792r1">From P0792R0 to P0792R1</h3>
<h4 id="changes">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="#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="#synopsis">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="#open-questions">Open questions</a></li>
<li><a href="#bikeshedding">Bikeshedding</a></li>
<li><a href="#acknowledgments">Acknowledgments</a></li>
<li><a href="#references">References</a></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>
<pre class="sourceCode cpp" id="cb1"><code class="sourceCode cpp"><a class="sourceLine" id="cb1-1" data-line-number="1"><span class="kw">struct</span> payload { <span class="co">/* ... */</span> };</a>
<a class="sourceLine" id="cb1-2" data-line-number="2"></a>
<a class="sourceLine" id="cb1-3" data-line-number="3"><span class="co">// Repeatedly invokes `action` up to `times` repetitions.</span></a>
<a class="sourceLine" id="cb1-4" data-line-number="4"><span class="co">// Immediately returns if `action` returns a valid `payload`.</span></a>
<a class="sourceLine" id="cb1-5" data-line-number="5"><span class="co">// Returns `std::nullopt` otherwise.</span></a>
<a class="sourceLine" id="cb1-6" data-line-number="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>
<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>
<pre class="sourceCode cpp" id="cb2"><code class="sourceCode cpp"><a class="sourceLine" id="cb2-1" data-line-number="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" data-line-number="2">                             <span class="bu">std::</span>optional&lt;payload&gt;(*action)())</a>
<a class="sourceLine" id="cb2-3" data-line-number="3">{</a>
<a class="sourceLine" id="cb2-4" data-line-number="4">    <span class="co">/* ... */</span></a>
<a class="sourceLine" id="cb2-5" data-line-number="5">}</a></code></pre>
<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>
<pre class="sourceCode cpp" id="cb3"><code class="sourceCode cpp"><a class="sourceLine" id="cb3-1" data-line-number="1"><span class="kw">template</span> &lt;<span class="kw">typename</span> F&gt;</a>
<a class="sourceLine" id="cb3-2" data-line-number="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" data-line-number="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" data-line-number="4">                        <span class="bu">std::</span>optional&lt;payload&gt;&gt;</a>
<a class="sourceLine" id="cb3-5" data-line-number="5">{</a>
<a class="sourceLine" id="cb3-6" data-line-number="6">    <span class="co">/* ... */</span></a>
<a class="sourceLine" id="cb3-7" data-line-number="7">}</a></code></pre>
<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>
<pre class="sourceCode cpp" id="cb4"><code class="sourceCode cpp"><a class="sourceLine" id="cb4-1" data-line-number="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" data-line-number="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" data-line-number="3">{</a>
<a class="sourceLine" id="cb4-4" data-line-number="4">    <span class="co">/* ... */</span></a>
<a class="sourceLine" id="cb4-5" data-line-number="5">}</a></code></pre>
<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>
<pre class="sourceCode cpp" id="cb5"><code class="sourceCode cpp"><a class="sourceLine" id="cb5-1" data-line-number="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" data-line-number="2">                             function_ref&lt;<span class="bu">std::</span>optional&lt;payload&gt;()&gt; action)</a>
<a class="sourceLine" id="cb5-3" data-line-number="3">{</a>
<a class="sourceLine" id="cb5-4" data-line-number="4">    <span class="co">/* ... */</span></a>
<a class="sourceLine" id="cb5-5" data-line-number="5">}</a></code></pre>
<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>
<pre class="sourceCode cpp" id="cb6"><code class="sourceCode cpp"><a class="sourceLine" id="cb6-1" data-line-number="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" data-line-number="2"><span class="co">// `f` could be referring to an existing Callable, or could own one.</span></a>
<a class="sourceLine" id="cb6-3" data-line-number="3"></a>
<a class="sourceLine" id="cb6-4" data-line-number="4"><span class="dt">void</span> bar(function_ref&lt;<span class="dt">void</span>()&gt; f);</a>
<a class="sourceLine" id="cb6-5" data-line-number="5"><span class="co">// `f` unambiguously is a non-owning reference to an existing Callable.</span></a></code></pre></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>
<pre class="sourceCode cpp" id="cb7"><code class="sourceCode cpp"><a class="sourceLine" id="cb7-1" data-line-number="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" data-line-number="2"></a>
<a class="sourceLine" id="cb7-3" data-line-number="3"><span class="dt">int</span> main()</a>
<a class="sourceLine" id="cb7-4" data-line-number="4">{</a>
<a class="sourceLine" id="cb7-5" data-line-number="5">    <span class="dt">int</span> x = <span class="dv">0</span>;</a>
<a class="sourceLine" id="cb7-6" data-line-number="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" data-line-number="7">}</a></code></pre>
<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"><sup>1</sup></a>.</p></li>
</ol>
<h2 id="synopsis">Synopsis</h2>
<pre class="sourceCode cpp" id="cb8"><code class="sourceCode cpp"><a class="sourceLine" id="cb8-1" data-line-number="1"><span class="kw">namespace</span> std</a>
<a class="sourceLine" id="cb8-2" data-line-number="2">{</a>
<a class="sourceLine" id="cb8-3" data-line-number="3">    <span class="kw">template</span> &lt;<span class="kw">typename</span> Signature&gt;</a>
<a class="sourceLine" id="cb8-4" data-line-number="4">    <span class="kw">class</span> function_ref</a>
<a class="sourceLine" id="cb8-5" data-line-number="5">    {</a>
<a class="sourceLine" id="cb8-6" data-line-number="6">    <span class="kw">public</span>:</a>
<a class="sourceLine" id="cb8-7" data-line-number="7">        <span class="kw">constexpr</span> function_ref(<span class="at">const</span> function_ref&amp;) <span class="kw">noexcept</span>;</a>
<a class="sourceLine" id="cb8-8" data-line-number="8"></a>
<a class="sourceLine" id="cb8-9" data-line-number="9">        <span class="kw">template</span> &lt;<span class="kw">typename</span> F&gt;</a>
<a class="sourceLine" id="cb8-10" data-line-number="10">        <span class="kw">constexpr</span> function_ref(F&amp;&amp;);</a>
<a class="sourceLine" id="cb8-11" data-line-number="11"></a>
<a class="sourceLine" id="cb8-12" data-line-number="12">        <span class="kw">constexpr</span> function_ref&amp; <span class="kw">operator</span>=(<span class="at">const</span> function_ref&amp;) <span class="kw">noexcept</span>;</a>
<a class="sourceLine" id="cb8-13" data-line-number="13"></a>
<a class="sourceLine" id="cb8-14" data-line-number="14">        <span class="kw">template</span> &lt;<span class="kw">typename</span> F&gt;</a>
<a class="sourceLine" id="cb8-15" data-line-number="15">        <span class="kw">constexpr</span> function_ref&amp; <span class="kw">operator</span>=(F&amp;&amp;);</a>
<a class="sourceLine" id="cb8-16" data-line-number="16"></a>
<a class="sourceLine" id="cb8-17" data-line-number="17">        <span class="kw">constexpr</span> <span class="dt">void</span> swap(function_ref&amp;) <span class="kw">noexcept</span>;</a>
<a class="sourceLine" id="cb8-18" data-line-number="18"></a>
<a class="sourceLine" id="cb8-19" data-line-number="19">        R <span class="kw">operator</span>()(Args...) qualifiers;</a>
<a class="sourceLine" id="cb8-20" data-line-number="20">        <span class="co">// `R`, `Args...`, and `qualifiers` are the return type, the parameter-type-list,</span></a>
<a class="sourceLine" id="cb8-21" data-line-number="21">        <span class="co">// and the sequence &quot;cv-qualifier-seq-opt noexcept-specifier-opt&quot; of the function</span></a>
<a class="sourceLine" id="cb8-22" data-line-number="22">        <span class="co">// type `Signature`, respectively.</span></a>
<a class="sourceLine" id="cb8-23" data-line-number="23">    };</a>
<a class="sourceLine" id="cb8-24" data-line-number="24"></a>
<a class="sourceLine" id="cb8-25" data-line-number="25">    <span class="kw">template</span> &lt;<span class="kw">typename</span> Signature&gt;</a>
<a class="sourceLine" id="cb8-26" data-line-number="26">    <span class="kw">constexpr</span> <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="cb8-27" data-line-number="27"></a>
<a class="sourceLine" id="cb8-28" data-line-number="28">    <span class="kw">template</span> &lt;<span class="kw">typename</span> R, <span class="kw">typename</span>... Args&gt;</a>
<a class="sourceLine" id="cb8-29" data-line-number="29">    function_ref(R (*)(Args...)) -&gt; function_ref&lt;R(Args...)&gt;;</a>
<a class="sourceLine" id="cb8-30" data-line-number="30"></a>
<a class="sourceLine" id="cb8-31" data-line-number="31">    <span class="kw">template</span> &lt;<span class="kw">typename</span> R, <span class="kw">typename</span>... Args&gt;</a>
<a class="sourceLine" id="cb8-32" data-line-number="32">    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="cb8-33" data-line-number="33"></a>
<a class="sourceLine" id="cb8-34" data-line-number="34">    <span class="kw">template</span> &lt;<span class="kw">typename</span> F&gt;</a>
<a class="sourceLine" id="cb8-35" data-line-number="35">    function_ref(F&amp;&amp;) -&gt; function_ref&lt;see below&gt;;</a>
<a class="sourceLine" id="cb8-36" data-line-number="36">}</a></code></pre>
<p>The template argument <code>Signature</code> shall be a non-<code>volatile</code>-qualified function type.</p>
<h3 id="functional-header"><code>&lt;functional&gt;</code> header</h3>
<p>Add the following to <code>[functional.syn]</code>:</p>
<pre class="sourceCode cpp" id="cb9"><code class="sourceCode cpp"><a class="sourceLine" id="cb9-1" data-line-number="1"><span class="kw">namespace</span> std</a>
<a class="sourceLine" id="cb9-2" data-line-number="2">{</a>
<a class="sourceLine" id="cb9-3" data-line-number="3">    <span class="co">// ...</span></a>
<a class="sourceLine" id="cb9-4" data-line-number="4"></a>
<a class="sourceLine" id="cb9-5" data-line-number="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="cb9-6" data-line-number="6"></a>
<a class="sourceLine" id="cb9-7" data-line-number="7">    <span class="kw">template</span> &lt;<span class="kw">typename</span> Signature&gt;</a>
<a class="sourceLine" id="cb9-8" data-line-number="8">    <span class="kw">constexpr</span> <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="cb9-9" data-line-number="9"></a>
<a class="sourceLine" id="cb9-10" data-line-number="10">    <span class="co">// ...</span></a>
<a class="sourceLine" id="cb9-11" data-line-number="11">}</a></code></pre>
<h2 id="specification">Specification</h2>
<pre class="sourceCode cpp" id="cb10"><code class="sourceCode cpp"><a class="sourceLine" id="cb10-1" data-line-number="1"><span class="kw">template</span> &lt;<span class="kw">typename</span> Signature&gt;</a>
<a class="sourceLine" id="cb10-2" data-line-number="2"><span class="kw">constexpr</span> function_ref&lt;Signature&gt;::function_ref(<span class="at">const</span> function_ref&amp; rhs) <span class="kw">noexcept</span>;</a></code></pre>
<ul>
<li><em>Effects:</em> constructs a <code>function_ref</code> referring to the same callable <code>rhs</code> refers to.</li>
</ul>
<p><br></p>
<pre class="sourceCode cpp" id="cb11"><code class="sourceCode cpp"><a class="sourceLine" id="cb11-1" data-line-number="1"><span class="kw">template</span> &lt;<span class="kw">typename</span> Signature&gt;</a>
<a class="sourceLine" id="cb11-2" data-line-number="2"><span class="kw">template</span> &lt;<span class="kw">typename</span> F&gt;</a>
<a class="sourceLine" id="cb11-3" data-line-number="3"><span class="kw">constexpr</span> function_ref&lt;Signature&gt;::function_ref(F&amp;&amp; f);</a></code></pre>
<ul>
<li><p><em>Requires:</em> none of the following must hold:</p>
<ul>
<li><p><code>f</code> is a null function pointer value.</p></li>
<li><p><code>f</code> is a null member pointer value.</p></li>
<li><p><code>F</code> is an instance of the <code>function</code> class template, and <code>!f</code>.</p></li>
</ul></li>
<li><p><em>Effects:</em> constructs a <code>function_ref</code> referring to <code>f</code>.</p></li>
<li><p><em>Remarks:</em> This constructor shall not participate in overload resolution unless <code>is_same_v&lt;decay_t&lt;F&gt;, function_ref&gt;</code> is <code>false</code> and:</p>
<ul>
<li><p>If <code>Signature</code> is marked <code>noexcept</code>: <code>is_nothrow_invocable_r_v&lt;R, cv-qualifiers F&amp;, Args...&gt;</code>;</p></li>
<li><p>Otherwise: <code>is_invocable_r_v&lt;R, cv-qualifiers F&amp;, Args...&gt;</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>
</ul>
<p><br></p>
<pre class="sourceCode cpp" id="cb12"><code class="sourceCode cpp"><a class="sourceLine" id="cb12-1" data-line-number="1"><span class="kw">template</span> &lt;<span class="kw">typename</span> Signature&gt;</a>
<a class="sourceLine" id="cb12-2" data-line-number="2"><span class="kw">constexpr</span> function_ref&amp; function_ref&lt;Signature&gt;::<span class="kw">operator</span>=(<span class="at">const</span> function_ref&amp; rhs) <span class="kw">noexcept</span>;</a></code></pre>
<ul>
<li><p><em>Postconditions:</em> <code>*this</code> refers to the same callable <code>rhs</code> refers to.</p></li>
<li><p><em>Returns:</em> <code>*this</code>.</p></li>
</ul>
<p><br></p>
<pre class="sourceCode cpp" id="cb13"><code class="sourceCode cpp"><a class="sourceLine" id="cb13-1" data-line-number="1"><span class="kw">template</span> &lt;<span class="kw">typename</span> Signature&gt;</a>
<a class="sourceLine" id="cb13-2" data-line-number="2"><span class="kw">template</span> &lt;<span class="kw">typename</span> F&gt;</a>
<a class="sourceLine" id="cb13-3" data-line-number="3"><span class="kw">constexpr</span> function_ref&amp; function_ref&lt;Signature&gt;::<span class="kw">operator</span>=(F&amp;&amp;);</a></code></pre>
<ul>
<li><p><em>Requires:</em> none of the following must hold:</p>
<ul>
<li><p><code>f</code> is a null function pointer value.</p></li>
<li><p><code>f</code> is a null member pointer value.</p></li>
<li><p><code>F</code> is an instance of the <code>function</code> class template, and <code>!f</code>.</p></li>
</ul></li>
<li><p><em>Remarks:</em> This function shall not participate in overload resolution unless <code>is_same_v&lt;decay_t&lt;F&gt;, function_ref&gt;</code> is <code>false</code> and:</p>
<ul>
<li><p>If <code>Signature</code> is marked <code>noexcept</code>: <code>is_nothrow_invocable_r_v&lt;R, cv-qualifiers F&amp;, Args...&gt;</code>;</p></li>
<li><p>Otherwise: <code>is_invocable_r_v&lt;R, cv-qualifiers F&amp;, Args...&gt;</code>.</p></li>
</ul></li>
<li><p><em>Postconditions:</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>
<pre class="sourceCode cpp" id="cb14"><code class="sourceCode cpp"><a class="sourceLine" id="cb14-1" data-line-number="1"><span class="kw">template</span> &lt;<span class="kw">typename</span> Signature&gt;</a>
<a class="sourceLine" id="cb14-2" data-line-number="2"><span class="kw">constexpr</span> <span class="dt">void</span> function_ref&lt;Signature&gt;::swap(function_ref&amp; rhs) <span class="kw">noexcept</span>;</a></code></pre>
<ul>
<li><em>Effects:</em> exchanges the values of <code>*this</code> and <code>rhs</code>.</li>
</ul>
<p><br></p>
<pre class="sourceCode cpp" id="cb15"><code class="sourceCode cpp"><a class="sourceLine" id="cb15-1" data-line-number="1"><span class="kw">template</span> &lt;<span class="kw">typename</span> Signature&gt;</a>
<a class="sourceLine" id="cb15-2" data-line-number="2">R function_ref&lt;Signature&gt;::<span class="kw">operator</span>()(Args... xs) qualifiers;</a></code></pre>
<ul>
<li><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>.</li>
</ul>
<p><br></p>
<pre class="sourceCode cpp" id="cb16"><code class="sourceCode cpp"><a class="sourceLine" id="cb16-1" data-line-number="1"><span class="kw">template</span> &lt;<span class="kw">typename</span> F&gt;</a>
<a class="sourceLine" id="cb16-2" data-line-number="2">function_ref(F&amp;&amp;) -&gt; function_ref&lt;see below&gt;;</a></code></pre>
<ul>
<li><em>Remarks:</em> This deduction guide participates in overload resolution only if <code>&amp;remove_reference_t&lt;F&gt;​::​operator()</code> is well-formed when treated as an unevaluated operand. In that case, if <code>decltype(&amp;remove_reference_t&lt;F&gt;::​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>, where <code>qualifiers</code> is the sequence “cv-qualifier-seq-opt noexcept-specifier-opt” of the function type <code>F</code>.</li>
</ul>
<p><br></p>
<pre class="sourceCode cpp" id="cb17"><code class="sourceCode cpp"><a class="sourceLine" id="cb17-1" data-line-number="1"><span class="kw">template</span> &lt;<span class="kw">typename</span> Signature&gt;</a>
<a class="sourceLine" id="cb17-2" data-line-number="2"><span class="kw">constexpr</span> <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>
<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>I propose the feature-testing macro name <code>__cpp_lib_function_ref</code>.</p>
<h2 id="example-implementation">Example implementation</h2>
<p>An example implementation is available <a href="https://github.com/SuperV1234/Experiments/blob/master/function_ref.cpp">here on GitHub</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"><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"><sup>3</sup></a>.</p></li>
<li><p>Facebook’s Folly libraries <a href="#fn4" class="footnote-ref" id="fnref4"><sup>4</sup></a> provide a <code>folly::FunctionRef</code> <a href="#fn5" class="footnote-ref" id="fnref5"><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"><sup>6</sup></a>.</p></li>
<li><p>GNU’s popular debugger, <code>gdb</code> <a href="#fn7" class="footnote-ref" id="fnref7"><sup>7</sup></a>, uses <code>gdb::function_view</code> <a href="#fn8" class="footnote-ref" id="fnref8"><sup>8</sup></a> throughout its code base. The documentation in the linked header file <a href="#fn9" class="footnote-ref" id="fnref9"><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"><sup>10</sup></a>, “<code>function_view</code>” <a href="#fn11" class="footnote-ref" id="fnref11"><sup>11</sup></a>, “<code>FunctionRef</code>” <a href="#fn12" class="footnote-ref" id="fnref12"><sup>12</sup></a>, and “<code>FunctionView</code>” <a href="#fn13" class="footnote-ref" id="fnref13"><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:</p>
<pre class="sourceCode cpp" id="cb18"><code class="sourceCode cpp"><a class="sourceLine" id="cb18-1" data-line-number="1"><span class="dt">void</span> foo(function_ref&lt;<span class="dt">void</span>()&gt;);</a>
<a class="sourceLine" id="cb18-2" data-line-number="2"></a>
<a class="sourceLine" id="cb18-3" data-line-number="3"><span class="dt">int</span> main()</a>
<a class="sourceLine" id="cb18-4" data-line-number="4">{</a>
<a class="sourceLine" id="cb18-5" data-line-number="5">    foo([]{ });</a>
<a class="sourceLine" id="cb18-6" data-line-number="6">}</a></code></pre>
<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>
<pre class="sourceCode cpp" id="cb19"><code class="sourceCode cpp"><a class="sourceLine" id="cb19-1" data-line-number="1"><span class="dt">int</span> main()</a>
<a class="sourceLine" id="cb19-2" data-line-number="2">{</a>
<a class="sourceLine" id="cb19-3" data-line-number="3">    function_ref&lt;<span class="dt">void</span>()&gt; f{[]{ }};</a>
<a class="sourceLine" id="cb19-4" data-line-number="4">    <span class="co">// ...</span></a>
<a class="sourceLine" id="cb19-5" data-line-number="5">    f(); <span class="co">// undefined behavior</span></a>
<a class="sourceLine" id="cb19-6" data-line-number="6">}</a></code></pre>
<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"><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"><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"><sup>16</sup></a> has the same problem <a href="#fn17" class="footnote-ref" id="fnref17"><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"><sup>18</sup></a> would prevent mistakes without limiting the usefulness of view/reference classes.</p>
<h2 id="open-questions">Open questions</h2>
<p>Below are some unanswered questions for which I kindly ask guidance from members of the commitee and readers of this paper.</p>
<ul>
<li><p><strong>(New in this revision)</strong> <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"><sup>19</sup></a> and N4159 <a href="#fn20" class="footnote-ref" id="fnref20"><sup>20</sup></a>) for additional context.</p></li>
<li><p><strong>(New in this revision)</strong> 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></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></li>
</ul>
<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="references">References</h2>
<section class="footnotes">
<hr />
<ol>
<li id="fn1"><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">↩</a></p></li>
<li id="fn2"><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">↩</a></p></li>
<li id="fn3"><p><a href="https://github.com/search?q=org%3Allvm-mirror+function_ref&amp;type=Code">https://github.com/search?q=org%3Allvm-mirror+function_ref&amp;type=Code</a><a href="#fnref3" class="footnote-back">↩</a></p></li>
<li id="fn4"><p><a href="https://github.com/facebook/folly" class="uri">https://github.com/facebook/folly</a><a href="#fnref4" class="footnote-back">↩</a></p></li>
<li id="fn5"><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">↩</a></p></li>
<li id="fn6"><p><a href="https://github.com/search?q=org%3Afacebook+FunctionRef&amp;type=Code">https://github.com/search?q=org%3Afacebook+FunctionRef&amp;type=Code</a><a href="#fnref6" class="footnote-back">↩</a></p></li>
<li id="fn7"><p><a href="https://www.gnu.org/software/gdb/" class="uri">https://www.gnu.org/software/gdb/</a><a href="#fnref7" class="footnote-back">↩</a></p></li>
<li id="fn8"><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">↩</a></p></li>
<li id="fn9"><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">↩</a></p></li>
<li id="fn10"><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">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">↩</a></p></li>
<li id="fn11"><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">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">↩</a></p></li>
<li id="fn12"><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">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">↩</a></p></li>
<li id="fn13"><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">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">↩</a></p></li>
<li id="fn14"><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">↩</a></p></li>
<li id="fn15"><p><a href="https://gist.github.com/SuperV1234/a41eb1c825bfbb43f595b13bd4ea99c3" class="uri">https://gist.github.com/SuperV1234/a41eb1c825bfbb43f595b13bd4ea99c3</a><a href="#fnref15" class="footnote-back">↩</a></p></li>
<li id="fn16"><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">↩</a></p></li>
<li id="fn17"><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">↩</a></p></li>
<li id="fn18"><p><a href="https://github.com/isocpp/CppCoreGuidelines/blob/master/docs/Lifetimes%20I%20and%20II%20-%20v0.9.1.pdf">https://github.com/isocpp/CppCoreGuidelines/blob/master/docs/Lifetimes%20I%20and%20II%20-%20v0.9.1.pdf</a><a href="#fnref18" class="footnote-back">↩</a></p></li>
<li id="fn19"><p><a href="http://wg21.link/p0045r1" class="uri">http://wg21.link/p0045r1</a><a href="#fnref19" class="footnote-back">↩</a></p></li>
<li id="fn20"><p><a href="http://wg21.link/N4159" class="uri">http://wg21.link/N4159</a><a href="#fnref20" class="footnote-back">↩</a></p></li>
</ol>
</section>
</body>
</html>
