<!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>
<colgroup>
<col style="width: 17%"></col>
<col style="width: 82%"></col>
</colgroup>
<tbody>
<tr class="odd">
<td>Document no.</td>
<td>P0915R0</td>
</tr>
<tr class="even">
<td>Date</td>
<td>2018-02-08</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;, John Lakos &lt;<a href="mailto:jlakos@bloomberg.net">jlakos@bloomberg.net</a>&gt;</td>
</tr>
<tr class="even">
<td>Audience</td>
<td>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="concept-constrained-auto"><em>Concept-constrained</em> <code>auto</code></h1>
<style>
.inline-link
{
    font-size: small;
    margin-top: -2.1em;
    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 a <em>concept-constrained</em> <code>auto</code> placeholder type for variables. The primary goal is to increase code readability and correctness without sacrificing genericity:</p>
<pre class="sourceCode cpp" id="cb1"><code class="sourceCode cpp"><a class="sourceLine" id="cb1-1" data-line-number="1"><span class="kw">template</span> &lt;<span class="kw">typename</span> T&gt;</a>
<a class="sourceLine" id="cb1-2" data-line-number="2"><span class="dt">void</span> foo(<span class="bu">std::</span>vector&lt;T&gt;&amp; v)</a>
<a class="sourceLine" id="cb1-3" data-line-number="3">{</a>
<a class="sourceLine" id="cb1-4" data-line-number="4">    <span class="kw">auto</span>&lt;RandomAccessIterator&gt; it{<span class="bu">std::</span>begin(v)};</a>
<a class="sourceLine" id="cb1-5" data-line-number="5">    <span class="co">// ...</span></a>
<a class="sourceLine" id="cb1-6" data-line-number="6">}</a></code></pre>
<h2 id="table-of-contents">Table of contents</h2>
<ul>
<li><a href="#overview">Overview</a></li>
<li><a href="#motivation">Motivation</a></li>
<li><a href="#proposed-syntax">Proposed syntax</a></li>
<li><a href="#wording">Wording</a></li>
<li><a href="#open-questions">Future directions</a></li>
<li><a href="#bikeshedding">Bikeshedding</a></li>
<li><a href="#references">References</a></li>
</ul>
<h2 id="overview">Overview</h2>
<p>A large part of the Concepts TS <a href="#fn1" class="footnote-ref" id="fnref1"><sup>1</sup></a> has been merged into the C++20 Standard working draft <a href="#fn2" class="footnote-ref" id="fnref2"><sup>2</sup></a>. Due to the lack of consensus and also to the existence of reasonable concerns, proposed features such as <strong>placeholders</strong> <em>(changes to <code>[dcl.spec.auto]</code>)</em> and <strong>abbreviated templates</strong> <em>(changes to <code>[dcl.fct]</code> and <code>[temp]</code>)</em> have not yet been merged into the working draft.</p>
<p>This paper proposes the introduction of a <em>concept-constrained</em> <code>auto</code> type placeholder, focusing on only the simplest, most common, and most impactful use case, while leaving the door open for future extensions.</p>
<p>The proposed <em>concept-constrained</em> <code>auto</code> enables users to specify a (constraining) <em>concept-name</em> when declaring variables using <code>auto</code>:</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>list&lt;<span class="dt">int</span>&gt; aList;</a>
<a class="sourceLine" id="cb2-2" data-line-number="2"></a>
<a class="sourceLine" id="cb2-3" data-line-number="3"><span class="co">// Unconstrained `auto`:</span></a>
<a class="sourceLine" id="cb2-4" data-line-number="4"><span class="kw">auto</span> i0 = <span class="bu">std::</span>begin(aList);</a>
<a class="sourceLine" id="cb2-5" data-line-number="5"></a>
<a class="sourceLine" id="cb2-6" data-line-number="6"><span class="co">// Well-formed usage of concept-constrained `auto`:</span></a>
<a class="sourceLine" id="cb2-7" data-line-number="7"><span class="kw">auto</span>&lt;BidirectionalIterator&gt; i1 = <span class="bu">std::</span>begin(aList);</a>
<a class="sourceLine" id="cb2-8" data-line-number="8"></a>
<a class="sourceLine" id="cb2-9" data-line-number="9"><span class="co">// Ill-formed usage of concept-constrained `auto`:</span></a>
<a class="sourceLine" id="cb2-10" data-line-number="10"><span class="kw">auto</span>&lt;RandomAccessIterator&gt; i2 = <span class="bu">std::</span>begin(aList); <span class="co">// &lt;== compile-time error</span></a></code></pre>
<h2 id="motivation">Motivation</h2>
<p>The current <em>unconstrained</em> <code>auto</code> placeholder works well in many scenarios:</p>
<ul>
<li><p><strong>When the type is obvious from the <em>initialization expression</em>:</strong></p>
<pre class="sourceCode cpp" id="cb3"><code class="sourceCode cpp"><a class="sourceLine" id="cb3-1" data-line-number="1"><span class="kw">auto</span> foo = <span class="bu">std::</span>make_shared&lt;Foo&gt;();</a></code></pre>
<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>map&lt;<span class="dt">int</span>, <span class="bu">std::</span>string&gt; aMap;</a>
<a class="sourceLine" id="cb4-2" data-line-number="2"><span class="kw">auto</span> it = <span class="bu">std::</span>begin(aMap);</a></code></pre></li>
<li><p><strong>When the type cannot be spelled out explicitly:</strong></p>
<pre class="sourceCode cpp" id="cb5"><code class="sourceCode cpp"><a class="sourceLine" id="cb5-1" data-line-number="1"><span class="kw">auto</span> lambda = []{ <span class="co">/* ... */</span>; };</a></code></pre></li>
<li><p><strong>Expression templates:</strong></p>
<pre class="sourceCode cpp" id="cb6"><code class="sourceCode cpp"><a class="sourceLine" id="cb6-1" data-line-number="1">Matrix a{<span class="co">/* ... */</span>}, b{<span class="co">/* ... */</span>}, c{<span class="co">/* ... */</span>};</a>
<a class="sourceLine" id="cb6-2" data-line-number="2"><span class="kw">auto</span> add = a + b;</a>
<a class="sourceLine" id="cb6-3" data-line-number="3"><span class="kw">auto</span> mul = add * c;</a>
<a class="sourceLine" id="cb6-4" data-line-number="4">consume(mul);</a></code></pre>
<p>In the snippet above, <code>mul</code> is not of type <code>Matrix</code>; its type encodes the sequence of operations as a compile-time expression tree. Using <code>Matrix</code> instead of <code>auto</code> could result in performance degradation.</p></li>
</ul>
<p>Unfortunately, the inability to constrain <code>auto</code> with a concept often results in less-readable code, sometimes with surprising results. Consider the following cases:</p>
<ul>
<li><p><strong>Invocation of functions in templated contexts:</strong></p>
<pre class="sourceCode cpp" id="cb7"><code class="sourceCode cpp"><a class="sourceLine" id="cb7-1" data-line-number="1"><span class="at">const</span> <span class="kw">auto</span>&amp; myEmployees = getEmployees();</a>
<a class="sourceLine" id="cb7-2" data-line-number="2"><span class="at">const</span> <span class="kw">auto</span>&amp; senior = mostExperiencedOf(myEmployees);</a></code></pre>
<p>Without reading the signatures <em>(and possibly even the implementations)</em> of <code>getEmployees</code> and <code>mostExperiencedOf</code>, it is unclear what kinds of types <code>myEmployees</code> and <code>senior</code> might be.</p>
<ul>
<li><blockquote>
<p>Is <code>myEmployees</code> a concrete container? Is it a lazily evaluated range?</p>
</blockquote></li>
<li><blockquote>
<p>Is <code>senior</code> a reference to an element inside <code>myEmployees</code>? Is it an <em>iterator</em>?</p>
</blockquote></li>
</ul>
<p>With the proposed <em>concept-constrained</em> <code>auto</code>, the code becomes more readable and explicit.</p>
<pre class="sourceCode cpp" id="cb8"><code class="sourceCode cpp"><a class="sourceLine" id="cb8-1" data-line-number="1"><span class="at">const</span> <span class="kw">auto</span>&lt;ContiguousContainer&gt;&amp; myEmployees = getEmployees();</a>
<a class="sourceLine" id="cb8-2" data-line-number="2"><span class="kw">auto</span>&lt;RandomAccessIterator&gt; senior = mostExperiencedOf(myEmployees);</a></code></pre>
<p>More generally, explicit specification of constraining concepts (as in the code snippet above) allows readers to have more refined knowledge about the properties of the types returned by <code>getEmployees</code> and <code>mostExperiencedOf</code>. The provided (named) constraints make the operations available on the returned values obvious (easily searchable), without sacrificing genericity or performance. Additionally, failure of the exact types to satify the requirement would be caught early <em>(at initialization, rather than at the point of usage)</em>.</p></li>
<li><p><strong>Making assumptions about types explicit:</strong></p>
<p>Imagine writing a function that copies the memory of a properly-aligned <em>standard layout</em> class to the GPU. Using (unconstrained) <code>auto</code> and no <em>static assertions</em> could result in undesirable behavior:</p>
<pre class="sourceCode cpp" id="cb9"><code class="sourceCode cpp"><a class="sourceLine" id="cb9-1" data-line-number="1"><span class="kw">template</span> &lt;<span class="kw">typename</span> Producer&gt;</a>
<a class="sourceLine" id="cb9-2" data-line-number="2"><span class="dt">void</span> uploadToGPU(Producer&amp; producer)</a>
<a class="sourceLine" id="cb9-3" data-line-number="3">{</a>
<a class="sourceLine" id="cb9-4" data-line-number="4">    <span class="kw">auto</span> item = producer.next();</a>
<a class="sourceLine" id="cb9-5" data-line-number="5">    gpuMemcpy(dst, &amp;item, <span class="kw">sizeof</span>(item)); <span class="co">// &lt;== Potentially UB</span></a>
<a class="sourceLine" id="cb9-6" data-line-number="6">}</a></code></pre>
<p>In the code snippet above, <code>gpuMemcpy</code> expects <code>&amp;item</code> to be a pointer to a <em>standard-layout</em> type, but there is nothing enforcing that to be true.</p>
<p>Adding a <code>static_assert</code> would prevent mistakes from happening, but might also (for some) detract from the readability of the code:</p>
<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> Producer&gt;</a>
<a class="sourceLine" id="cb10-2" data-line-number="2"><span class="dt">void</span> uploadToGPU(Producer&amp; producer)</a>
<a class="sourceLine" id="cb10-3" data-line-number="3">{</a>
<a class="sourceLine" id="cb10-4" data-line-number="4">    <span class="kw">auto</span> item = producer.next();</a>
<a class="sourceLine" id="cb10-5" data-line-number="5">    <span class="kw">static_assert</span>(StandardLayoutType&lt;<span class="kw">decltype</span>(item)&gt;);</a>
<a class="sourceLine" id="cb10-6" data-line-number="6">    gpuMemcpy(dst, &amp;item, <span class="kw">sizeof</span>(item));</a>
<a class="sourceLine" id="cb10-7" data-line-number="7">}</a></code></pre>
<p>Using the proposed <em>concept-constrained</em> <code>auto</code> would achieve a safe and clear result with minimal boilerplate:</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> Producer&gt;</a>
<a class="sourceLine" id="cb11-2" data-line-number="2"><span class="dt">void</span> uploadToGPU(Producer&amp; producer)</a>
<a class="sourceLine" id="cb11-3" data-line-number="3">{</a>
<a class="sourceLine" id="cb11-4" data-line-number="4">    <span class="kw">auto</span>&lt;StandardLayoutType&gt; item = producer.next();</a>
<a class="sourceLine" id="cb11-5" data-line-number="5">    gpuMemcpy(dst, &amp;item, <span class="kw">sizeof</span>(item));</a>
<a class="sourceLine" id="cb11-6" data-line-number="6">}</a></code></pre></li>
</ul>
<p>We are confident that proper use of <em>concept-constrained</em> <code>auto</code>, where appropriate, will significantly increase the readability and accessibility of Modern C++ programs, especially in large code bases. Note that we are not suggesting that <em>concept-constrained</em> <code>auto</code> should always be preferred to (unconstrained) <code>auto</code> -- there are common situations where supplying the optional constraint would be counter indicated:</p>
<pre class="sourceCode cpp" id="cb12"><code class="sourceCode cpp"><a class="sourceLine" id="cb12-1" data-line-number="1">Employee* Company::findFirstSeniorEmployee() <span class="at">const</span></a>
<a class="sourceLine" id="cb12-2" data-line-number="2">{</a>
<a class="sourceLine" id="cb12-3" data-line-number="3">    <span class="kw">auto</span>&lt;Iterator&gt; it = <span class="bu">std::</span>begin(<span class="kw">this</span>-&gt;d_employees);</a>
<a class="sourceLine" id="cb12-4" data-line-number="4"><span class="co">//      ^~~~~~~~~~</span></a>
<a class="sourceLine" id="cb12-5" data-line-number="5"></a>
<a class="sourceLine" id="cb12-6" data-line-number="6">    <span class="co">// ...business logic...</span></a>
<a class="sourceLine" id="cb12-7" data-line-number="7">    <span class="cf">return</span> it == <span class="bu">std::</span>end(<span class="kw">this</span>-&gt;d_employees) ? <span class="kw">nullptr</span></a>
<a class="sourceLine" id="cb12-8" data-line-number="8">                                             : &amp;*it;</a>
<a class="sourceLine" id="cb12-9" data-line-number="9">}</a></code></pre>
<p>In the example above, the identifier <code>it</code> is already clearly some form of <code>Iterator</code>. Moreover, the <code>Iterator</code> concept, along with its idiomatic use as being what is expected of the return types for <code>begin()</code> and <code>end()</code> methods, are familiar to virtually every C++ developer. (We refer to such ubiquitously familiar concepts as <strong>vocabulary concepts</strong>). Making <code>Iterator</code> an explicit (named) constraint to <code>auto</code> here would be pointless noise – arguably detracting from readability. If, on the other hand, it were the case that (1) the code did not as yet make explicit use of <em>random-access-iterator</em> features, and (2) it was foreseeable that such features would soon be required, then constraining the <code>auto</code> with <code>RandomAccessIterator</code> is exactly what would express that engineering intent:</p>
<pre class="sourceCode cpp" id="cb13"><code class="sourceCode cpp"><a class="sourceLine" id="cb13-1" data-line-number="1">Employee* Company::findFirstSeniorEmployee() <span class="at">const</span></a>
<a class="sourceLine" id="cb13-2" data-line-number="2">{</a>
<a class="sourceLine" id="cb13-3" data-line-number="3">    <span class="kw">auto</span>&lt;RandomAccessIterator&gt; it = <span class="bu">std::</span>begin(<span class="kw">this</span>-&gt;d_employees);</a>
<a class="sourceLine" id="cb13-4" data-line-number="4"><span class="co">//      ^~~~~~~~~~~~~~~~~~~~~</span></a>
<a class="sourceLine" id="cb13-5" data-line-number="5"><span class="co">//      Required to express engineering intent.</span></a>
<a class="sourceLine" id="cb13-6" data-line-number="6"></a>
<a class="sourceLine" id="cb13-7" data-line-number="7">    <span class="co">// ...business logic that does not require a `RandomAccessIterator` (yet)...</span></a>
<a class="sourceLine" id="cb13-8" data-line-number="8">    <span class="cf">return</span> it == <span class="bu">std::</span>end(<span class="kw">this</span>-&gt;d_employees) ? <span class="kw">nullptr</span></a>
<a class="sourceLine" id="cb13-9" data-line-number="9">                                             : &amp;*it;</a>
<a class="sourceLine" id="cb13-10" data-line-number="10">}</a></code></pre>
<p>From an engineering standpoint, however, the use of <em>concept-constrained</em> <code>auto</code> becomes imperative, when dealing with <strong>non-vocabulary</strong> concepts, as this compiler-enforced “documentation” dramatically facilitates developers becoming familiar with previously unseen concepts by name, which – in turn – can be more easily looked up if need be:</p>
<pre class="sourceCode cpp" id="cb14"><code class="sourceCode cpp"><a class="sourceLine" id="cb14-1" data-line-number="1"><span class="dt">void</span> Employee::logStatus() <span class="at">const</span></a>
<a class="sourceLine" id="cb14-2" data-line-number="2">{</a>
<a class="sourceLine" id="cb14-3" data-line-number="3">    <span class="kw">auto</span>&lt;bdex::OutStream&gt;&amp; stream = getLogStream();</a>
<a class="sourceLine" id="cb14-4" data-line-number="4"><span class="co">//      ^~~~~~~~~~~~~~~~~</span></a>
<a class="sourceLine" id="cb14-5" data-line-number="5"></a>
<a class="sourceLine" id="cb14-6" data-line-number="6">    stream.putString(<span class="kw">this</span>-&gt;d_name);</a>
<a class="sourceLine" id="cb14-7" data-line-number="7">    stream.putUint32(<span class="kw">this</span>-&gt;d_userId);</a>
<a class="sourceLine" id="cb14-8" data-line-number="8">    stream.putUint8(<span class="kw">this</span>-&gt;d_statusFlags);</a>
<a class="sourceLine" id="cb14-9" data-line-number="9">}</a></code></pre>
<p>Developers reading the function above will benefit greatly from the explicit <code>bdex::OutStream</code> concept constraint, especially those who find it unfamiliar:</p>
<ul>
<li><p>Being able to see <code>bdex::OutStream</code> gives readers a name to search for in the code base and its documentation to understand the scope and functionality of the concept.</p></li>
<li><p>The <code>auto&lt;...&gt;</code> notation <em>(as opposed to the “as yet to be adopted” terse notation)</em> makes it unambiguously clear that <code>bdex::OutStream</code> is a <em>concept</em> and <strong>not</strong> a <em>type</em>.</p></li>
</ul>
<p>If (unconstained) <code>auto</code> were used, the reader would need to check the declaration of <code>getLogStream()</code> <em>(and possibly its definition)</em> in order to understand what kind of object was being returned.</p>
<h2 id="proposed-syntax">Proposed syntax</h2>
<p>We propose the ability of constraining <code>auto</code> with a concept, independently of cv-qualifiers. E.g.</p>
<pre class="sourceCode cpp" id="cb15"><code class="sourceCode cpp"><a class="sourceLine" id="cb15-1" data-line-number="1"><span class="kw">auto</span>&lt;Iterator&gt; i0 = foo();</a>
<a class="sourceLine" id="cb15-2" data-line-number="2"><span class="kw">auto</span>&lt;BidirectionalIterator&gt;&amp;&amp; i1 = foo();</a>
<a class="sourceLine" id="cb15-3" data-line-number="3"><span class="at">const</span> <span class="at">volatile</span> <span class="kw">auto</span>&lt;MoveConstructible&gt;&amp; i2 = bar();</a></code></pre>
<h2 id="wording">Wording</h2>
<p>The proposed wording copies the terminology used in N4674 in order to make future extensions easier to apply.</p>
<h3 id="dcl.type.simple"><code>[dcl.type.simple]</code></h3>
<ul>
<li><p>Add <em>constrained-type-specifier</em> to the grammar for <em>simple-type-specifiers</em>.</p></li>
<li><p>Modify paragraph 2 to begin:</p>
<ul>
<li><del>The <em>simple-type-specifier</em> <code>auto</code> specifier is a placeholder for a type to be deduced (10.1.7.4).</del> The <em>simple-type-specifier</em> <code>auto</code> and <em>constrained-type-specifiers</em> are placeholders for a type to be deduced (10.1.7.4).</li>
</ul></li>
<li><p>Add <em>constrained-type-specifier</em> to the table of simple-type-specifiers in Table 11:</p>
<table>
<thead>
<tr class="header">
<th>Specifier(s)</th>
<th>Type</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>constrained-type-specifier</td>
<td>placeholder for type to be deduced</td>
</tr>
</tbody>
</table></li>
</ul>
<h3 id="dcl.spec.auto"><code>[dcl.spec.auto]</code></h3>
<ul>
<li><p>Modify paragraph 1 to begin:</p>
<ul>
<li><del>The <code>auto</code> and <code>decltype(auto)</code> <em>type-specifiers</em> are used to designate a placeholder type that will be replaced later by deduction from an initializer.</del> The <code>auto</code> and <code>decltype(auto)</code> <em>type-specifiers</em>, and <em>constrained-type-specifier</em> are used to designate a placeholder type that will be replaced later by deduction from an initializer.</li>
</ul></li>
</ul>
<h3 id="dcl.spec.auto.deduct"><code>[dcl.spec.auto.deduct]</code></h3>
<ul>
<li><p>Modify paragraph 3 to begin:</p>
<ul>
<li><del>If the placeholder is the <code>auto</code> <em>type-specifier</em>, the deduced type <code>T'</code> replacing <code>T</code> is determined using the rules for template argument deduction.</del> If the placeholder is the <code>auto</code> <em>type-specifier</em> or a <em>constrained-type-specifier</em>, the deduced type <code>T'</code> replacing <code>T</code> is determined using the rules for template argument deduction.</li>
</ul></li>
<li><p>Modify paragraph 3:</p>
<ul>
<li><del>Deduce a value for <code>U</code> using the rules of template argument deduction from a function call (17.8.2.1), where <code>P</code> is a function template parameter type and the corresponding argument is <code>e</code>. If the deduction fails, the declaration is ill-formed.</del> Deduce a value for <code>U</code> using the rules of template argument deduction from a function call (17.8.2.1), where <code>P</code> is a function template parameter type and the corresponding argument is <code>e</code>. If the deduction fails, the declaration is ill-formed. If the used placeholder is a <em>constrained-type-specifier</em> with an associated constraint <code>C</code>, the declaration is ill-formed if <code>C&lt;U&gt;</code> evaluates to <code>false</code>.</li>
</ul></li>
</ul>
<h3 id="dcl.spec.auto.constr"><code>[dcl.spec.auto.constr]</code></h3>
<ul>
<li><p>Add this section to 10.1.7.4.</p></li>
<li><p>Paragraph 1:</p>
<ul>
<li><p>A <em>constrained-type-specifier</em> designates a placeholder type and introduces an associated constraint.</p>
<ul>
<li><p><em>constrained-type-specifier</em>:</p>
<ul>
<li><code>auto</code> &lt; <em>qualified-concept-name</em> &gt;</li>
</ul></li>
</ul></li>
</ul>
<p>[<em>Example:</em></p>
<pre><code>    template&lt;typename T&gt; concept bool C0 = true;
    int f0() { return 42; }
    void f1()
    {
        auto&lt;C0&gt; i = f0(); // auto&lt;C0&gt; designates a placeholder type
                           // with associated constraint C0
    }</code></pre>
<p>]</p></li>
</ul>
<h2 id="future-directions">Future directions</h2>
<p>This proposal is meant to be as simple as possible but leaves room for future extensions.</p>
<ul>
<li><p><em>Concept-constrained</em> <code>auto</code> placeholders could be extended to work as function parameter types and also as function return types:</p>
<pre class="sourceCode cpp" id="cb17"><code class="sourceCode cpp"><a class="sourceLine" id="cb17-1" data-line-number="1"><span class="kw">auto</span> l0 = [](<span class="kw">auto</span>&lt;ForwardIterator&gt; x){ <span class="co">/* ... */</span> };</a>
<a class="sourceLine" id="cb17-2" data-line-number="2"><span class="kw">auto</span> foo() -&gt; <span class="kw">auto</span>&lt;MoveConstructible&gt; { <span class="co">/* ... */</span> };</a></code></pre></li>
<li><p>A terser syntax <em>(such as the one already specified in the concepts TS)</em> that doesn’t require <code>auto&lt;...&gt;</code> to introduce a type placeholder could be incorporated - the concept name on its own would be enough:</p>
<pre class="sourceCode cpp" id="cb18"><code class="sourceCode cpp"><a class="sourceLine" id="cb18-1" data-line-number="1">ForwardIterator it = foo();</a></code></pre>
<p><em>…equivalent to…</em></p>
<pre class="sourceCode cpp" id="cb19"><code class="sourceCode cpp"><a class="sourceLine" id="cb19-1" data-line-number="1"><span class="kw">auto</span>&lt;ForwardIterator&gt; it = foo();</a></code></pre>
<p>Note that the proposed syntax is <strong>not</strong> intended to be a temporary solution until consensus on the terse syntax is reached. We believe that <em>concept-constrained</em> <code>auto</code> will always be needed even if (when) the terse syntax is voted into the Standard, thanks to its more descriptive and explicit value - especially in public APIs.</p>
<p>Additionally, note that:</p>
<pre class="sourceCode cpp" id="cb20"><code class="sourceCode cpp"><a class="sourceLine" id="cb20-1" data-line-number="1">ForwardIteratorConcept it = foo();</a></code></pre>
<p>and</p>
<pre class="sourceCode cpp" id="cb21"><code class="sourceCode cpp"><a class="sourceLine" id="cb21-1" data-line-number="1"><span class="kw">auto</span>&lt;ForwardIterator&gt; it = foo();</a></code></pre>
<p>have roughly the same number of characters. Yet, <code>ForwardIteratorConcept</code> is known to be a <em>concept</em> due only to convention, whereas <code>auto&lt;ForwardIterator&gt;</code> implies that <code>ForwardIterator</code> is unambiguously a <em>concept</em>. So, regardless of whether or not <em>terse syntax</em> will ever make it into the Standard, the feature we have proposed in this paper is <strong>necessary</strong> to allow developers to be unambiguously explicit when referring to <strong>non-vocabulary</strong> concepts.</p></li>
<li><p>Logical composition of concepts could be allowed inside the <code>&lt;...&gt;</code> angle brackets:</p>
<pre class="sourceCode cpp" id="cb22"><code class="sourceCode cpp"><a class="sourceLine" id="cb22-1" data-line-number="1"><span class="kw">auto</span>&lt;Erasable &amp;&amp; MoveConstructible&gt; = bar();</a></code></pre></li>
</ul>
<p>The goal of this proposal is to introduce a simplified yet useful minimal subset of the proposed <em>placeholder</em> sections in the Concepts working draft. <em>Concept-constrained</em> <code>auto</code>’s scope and functionality can then be expanded in the future to reach the power and flexibility of the original design.</p>
<h2 id="bikeshedding">Bikeshedding</h2>
<p><code>&lt;...&gt;</code> is, in our view, the optimal choice due to its clear, concise, and expressive syntax. Unfortunately, it might not be appropriate as it misleadingly suggests <em>template instantiation</em>. Andrew Sutton recommended using the <code>auto|Concept</code> syntax instead, which was part of the original proposal for concepts but was dropped in favor of the <em>terse notation</em> which we have already addressed. There exist other viable possibilities for the <em>concept-constrained</em> <code>auto</code> syntax:</p>
<ul>
<li><p><code>auto{Concept}</code></p></li>
<li><p><code>auto:Concept</code></p></li>
<li><p><code>auto Concept</code></p></li>
</ul>
<p>We have not considered <code>auto(Concept)</code> and <code>auto[Concept]</code> because they respectively conflict with <em>variable initialization</em> and <em>structured bindings</em>.</p>
<h2 id="references">References</h2>
<ul>
<li><p>“A plea for a consistent, terse and intuitive declaration syntax”:</p>
<ul>
<li><p><a href="https://groups.google.com/a/isocpp.org/forum/#!topic/std-proposals/yEoi0vEnJ48" class="uri">https://groups.google.com/a/isocpp.org/forum/#!topic/std-proposals/yEoi0vEnJ48</a></p></li>
<li><p><a href="https://cor3ntin.github.io/CPPProposals/unified_concept_declaration_syntax/concepts.html" class="uri">https://cor3ntin.github.io/CPPProposals/unified_concept_declaration_syntax/concepts.html</a></p></li>
</ul></li>
<li><p>“Remove abbreviated functions and template-introduction syntax from the Concepts TS”:</p>
<ul>
<li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0696r0.html" class="uri">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0696r0.html</a></li>
</ul></li>
<li><p>“Concepts are Adjectives, not Nouns”</p>
<ul>
<li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0791r0.pdf" class="uri">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0791r0.pdf</a></li>
</ul></li>
<li><p>“An Adjective Syntax for Concepts”</p>
<ul>
<li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0807r0.html" class="uri">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0807r0.html</a></li>
</ul></li>
</ul>
<section class="footnotes">
<hr />
<ol>
<li id="fn1"><p><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4674.pdf" class="uri">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4674.pdf</a><a href="#fnref1" class="footnote-back">↩</a></p></li>
<li id="fn2"><p><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4700.pdf" class="uri">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4700.pdf</a><a href="#fnref2" class="footnote-back">↩</a></p></li>
</ol>
</section>
</body>
</html>
