<!DOCTYPE html>
<html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>P0658R0 -- Proposal for adding alias declarations to concepts</title>
  </head>
  <body>
    <div class="container markdown-body">
      <p><strong>Document Number:</strong> P0658R0</p>

<p><strong>Date:</strong> 2017-06-11</p>

<p><strong>Audience:</strong> Evolution Working Group</p>

<p><strong>Reply-to:</strong> Christopher Di Bella &lt;cjdb.ns@gmail.com&gt;</p>

<h1 id="proposal-for-adding-alias-declarations-to-concepts">Proposal for adding alias declarations to concepts<a class="anchorjs-link " href="#proposal-for-adding-alias-declarations-to-concepts" aria-label="Anchor link for: proposal for adding alias declarations to concepts" data-anchorjs-icon="" style="font-style: normal; font-variant: normal; font-weight: normal; font-stretch: normal; font-size: 1em; line-height: 1; font-family: anchorjs-icons; padding-left: 0.375em;"></a></h1>

<h2 id="abstract">Abstract<a class="anchorjs-link " href="#abstract" aria-label="Anchor link for: abstract" data-anchorjs-icon="" style="font-style: normal; font-variant: normal; font-weight: normal; font-stretch: normal; font-size: 1em; line-height: 1; font-family: anchorjs-icons; padding-left: 0.375em;"></a></h2>

<p>This document proposes to add <em>alias-declarations</em> to <em>requirement-bodies</em> so that types may be renamed without the need for creating exposition-only concepts that have additional template typenames for convenience and readability.</p>

<h2 id="table-of-contents">Table of contents<a class="anchorjs-link " href="#table-of-contents" aria-label="Anchor link for: table of contents" data-anchorjs-icon="" style="font-style: normal; font-variant: normal; font-weight: normal; font-stretch: normal; font-size: 1em; line-height: 1; font-family: anchorjs-icons; padding-left: 0.375em;"></a></h2>

<ul>
  <li><a href="#primary-motivation">Primary motivation</a>
    <ul>
      <li><a href="#motivation1">Motivation 1</a></li>
      <li><a href="#motivation2">Motivation 2</a></li>
    </ul>
  </li>
  <li><a href="#proposals">Proposals</a>
    <ul>
      <li><a href="#proposal1">Proposal 1</a></li>
      <li><a href="#proposal2">Proposal 2</a></li>
      <li><a href="#proposal3">Proposal 3</a></li>
    </ul>
  </li>
  <li><a href="#conclusion">Conclusion</a></li>
  <li><a href="#acknowledgement">Acknowledgements</a></li>
</ul>

<h2 id="primary-motivation">Primary motivation<a class="anchorjs-link " href="#primary-motivation" aria-label="Anchor link for: primary motivation" data-anchorjs-icon="" style="font-style: normal; font-variant: normal; font-weight: normal; font-stretch: normal; font-size: 1em; line-height: 1; font-family: anchorjs-icons; padding-left: 0.375em;"></a></h2>

<h3 id="motivation-1">Motivation 1<a class="anchorjs-link " href="#motivation-1" aria-label="Anchor link for: motivation 1" data-anchorjs-icon="" style="font-style: normal; font-variant: normal; font-weight: normal; font-stretch: normal; font-size: 1em; line-height: 1; font-family: anchorjs-icons; padding-left: 0.375em;"></a></h3>

<p>Concepts are fun to work with, and fun to design, but anything with more than a few names is tedious to type up, and tedious to read. Consider this rather verbose attempt at drafting a concept for a sequence container:</p>

<div class="language-cpp highlighter-rouge"><pre class="highlight"><code><span class="c1">// using value_type_t, difference_type_t, and concepts from Ranges TS
</span><span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">X</span><span class="p">,</span> <span class="k">typename</span><span class="p">...</span> <span class="n">Args</span><span class="o">&gt;</span>
<span class="n">concept</span> <span class="kt">bool</span> <span class="n">SequenceContaioner</span> <span class="o">=</span> <span class="n">Container</span><span class="o">&lt;</span><span class="n">X</span><span class="o">&gt;</span> <span class="o">&amp;&amp;</span> <span class="n">requires</span> <span class="p">{</span>
   <span class="k">typename</span> <span class="n">value_type_t</span><span class="o">&lt;</span><span class="n">X</span><span class="o">&gt;</span><span class="p">;</span>
   <span class="k">typename</span> <span class="n">difference_type_t</span><span class="o">&lt;</span><span class="n">X</span><span class="o">&gt;</span><span class="p">;</span>
   <span class="n">requires</span> <span class="n">Constructible</span><span class="o">&lt;</span><span class="n">X</span><span class="p">,</span> <span class="n">difference_type_t</span><span class="o">&lt;</span><span class="n">X</span><span class="o">&gt;</span><span class="p">,</span> <span class="n">value_type_t</span><span class="o">&lt;</span><span class="n">X</span><span class="o">&gt;&gt;</span><span class="p">();</span>
   <span class="n">requires</span> <span class="n">Construictible</span><span class="o">&lt;</span><span class="n">X</span><span class="p">,</span> <span class="n">initializer_list</span><span class="o">&lt;</span><span class="n">value_type_t</span><span class="o">&lt;</span><span class="n">X</span><span class="o">&gt;&gt;&gt;</span><span class="p">();</span>
   <span class="n">requires</span> <span class="n">Assignable</span><span class="o">&lt;</span><span class="n">X</span><span class="o">&amp;</span><span class="p">,</span> <span class="n">initializer_list</span><span class="o">&lt;</span><span class="n">value_type_t</span><span class="o">&lt;</span><span class="n">X</span><span class="o">&gt;&gt;&gt;</span><span class="p">();</span>
   <span class="c1">// ...
</span><span class="p">};</span>
</code></pre>
</div>

<p>Our current <code class="highlighter-rouge">SequenceContainer</code> is quite jarring to read, so we might like to split it into <code class="highlighter-rouge">SequenceContainer</code> and <code class="highlighter-rouge">detail::SequenceConstructible</code>:</p>

<div class="language-cpp highlighter-rouge"><pre class="highlight"><code><span class="k">namespace</span> <span class="n">detail</span> <span class="p">{</span>
   <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">X</span><span class="p">,</span> <span class="k">typename</span> <span class="n">T</span><span class="p">,</span> <span class="k">typename</span> <span class="n">D</span><span class="p">,</span> <span class="k">typename</span><span class="p">...</span> <span class="n">Args</span><span class="o">&gt;</span>
   <span class="n">concept</span> <span class="kt">bool</span> <span class="n">SequenceConstructible</span> <span class="o">=</span> <span class="n">Constructible</span><span class="o">&lt;</span><span class="n">X</span><span class="p">,</span> <span class="n">D</span><span class="p">,</span> <span class="n">T</span><span class="o">&gt;</span><span class="p">()</span> <span class="o">&amp;&amp;</span>
      <span class="n">Constructible</span><span class="o">&lt;</span><span class="n">X</span><span class="p">,</span> <span class="n">initializer_list</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;&gt;</span><span class="p">()</span> <span class="o">&amp;&amp;</span>
      <span class="n">Assignable</span><span class="o">&lt;</span><span class="n">X</span><span class="o">&amp;</span><span class="p">,</span> <span class="n">initializer_list</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;&gt;</span><span class="p">()</span>
      <span class="c1">// ...
</span>   <span class="p">;</span>
   <span class="c1">// Other SequenceContainer details here...
</span><span class="p">}</span> <span class="c1">// namespace detail
</span>
<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">X</span><span class="p">,</span> <span class="k">typename</span><span class="p">...</span> <span class="n">Args</span><span class="o">&gt;</span>
<span class="n">concept</span> <span class="kt">bool</span> <span class="n">SequenceContainer</span> <span class="o">=</span> <span class="n">Container</span><span class="o">&lt;</span><span class="n">X</span><span class="o">&gt;</span> <span class="o">&amp;&amp;</span>
   <span class="n">detail</span><span class="o">::</span><span class="n">SequenceConstructible</span><span class="o">&lt;</span><span class="n">X</span><span class="p">,</span> <span class="n">value_type_t</span><span class="o">&lt;</span><span class="n">X</span><span class="o">&gt;</span><span class="p">,</span> <span class="n">difference_type_t</span><span class="o">&lt;</span><span class="n">X</span><span class="o">&gt;</span><span class="p">,</span> <span class="n">Args</span><span class="p">...</span><span class="o">&gt;</span> <span class="c1">// &amp;&amp;
</span>   <span class="c1">// ...
</span><span class="p">;</span>
</code></pre>
</div>

<p>Now we can read the implementation of a <code class="highlighter-rouge">SequenceContainer</code> without the added noise of <code class="highlighter-rouge">value_type_t&lt;X&gt;</code>, <code class="highlighter-rouge">difference_type_t&lt;X&gt;</code>, and <code class="highlighter-rouge">initializer_list&lt;value_type_t&lt;X&gt;&gt;</code> at every turn, but we’ve now created a second, exposition-only concept with exactly one use-case: to facilitate the readability of our usable concept that (hopefully!) has many use-cases. Furthermore, we need to find a meaningful name for our exposition-only concepts so that they are easy to understand.</p>

<h4 id="desired-outcome">Desired outcome<a class="anchorjs-link " href="#desired-outcome" aria-label="Anchor link for: desired outcome" data-anchorjs-icon="" style="font-style: normal; font-variant: normal; font-weight: normal; font-stretch: normal; font-size: 1em; line-height: 1; font-family: anchorjs-icons; padding-left: 0.375em;"></a></h4>

<p>It would be nice to have something that resembles:</p>

<div class="language-diff highlighter-rouge"><pre class="highlight"><code>template &lt;typename X, typename... Args&gt;
concept bool SequenceContainer = Container&lt;X&gt; &amp;&amp; requires {
<span class="gi">+   requires using value_type = value_type_t&lt;X&gt;; // type alias value_type, typename requirement for value_type_t&lt;X&gt;
+   requires using difference_type = difference_type_t&lt;X&gt;;
+   using initializer_list_type = initializer_list&lt;value_type&gt;; // just a type alias
</span>
   requires Constructible&lt;X, difference_type, value_type&gt;();
   requires Constructible&lt;X, initializer_list_type&gt;();
   requires Assignable&lt;X&amp;, initializer_list_type&gt;();
   // ...
};
</code></pre>
</div>

<h4 id="why-is-this-desirable-given-the-above-motivation">Why is this desirable, given the above motivation?<a class="anchorjs-link " href="#why-is-this-desirable-given-the-above-motivation" aria-label="Anchor link for: why is this desirable given the above motivation" data-anchorjs-icon="" style="font-style: normal; font-variant: normal; font-weight: normal; font-stretch: normal; font-size: 1em; line-height: 1; font-family: anchorjs-icons; padding-left: 0.375em;"></a></h4>

<p>Exposition-only concepts that exist solely to improve readability are removed.</p>

<h3 id="motivation-2">Motivation 2<a class="anchorjs-link " href="#motivation-2" aria-label="Anchor link for: motivation 2" data-anchorjs-icon="" style="font-style: normal; font-variant: normal; font-weight: normal; font-stretch: normal; font-size: 1em; line-height: 1; font-family: anchorjs-icons; padding-left: 0.375em;"></a></h3>

<p>Let’s now consider an attempt to turn <code class="highlighter-rouge">std::inner_product</code> into a concept-checked <code class="highlighter-rouge">inner_product</code>:</p>

<div class="language-cpp highlighter-rouge"><pre class="highlight"><code><span class="k">template</span> <span class="o">&lt;</span><span class="n">InputIterator</span> <span class="n">I1</span><span class="p">,</span> <span class="n">Sentinel</span><span class="o">&lt;</span><span class="n">I1</span><span class="o">&gt;</span> <span class="n">S1</span><span class="p">,</span> <span class="n">InputIterator</span> <span class="n">I2</span><span class="p">,</span> <span class="n">Sentinel</span><span class="o">&lt;</span><span class="n">I2</span><span class="o">&gt;</span> <span class="n">S2</span><span class="p">,</span>
   <span class="n">CopyConstructible</span> <span class="n">T</span><span class="p">,</span>
   <span class="k">typename</span> <span class="n">Proj1</span> <span class="o">=</span> <span class="n">identity</span><span class="p">,</span> <span class="k">typename</span> <span class="n">Proj2</span> <span class="o">=</span> <span class="n">identity</span><span class="p">,</span>
   <span class="n">IndirectRegularInvocable</span><span class="o">&lt;</span><span class="n">projected</span><span class="o">&lt;</span><span class="n">I1</span><span class="p">,</span> <span class="n">Proj1</span><span class="o">&gt;</span><span class="p">,</span>
      <span class="n">projected</span><span class="o">&lt;</span><span class="n">I2</span><span class="p">,</span> <span class="n">Proj2</span><span class="o">&gt;&gt;</span> <span class="n">Op2</span> <span class="o">=</span> <span class="n">multiplies</span><span class="o">&lt;&gt;</span><span class="p">,</span>
   <span class="n">RegularInvocable</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span>
      <span class="n">indirect_result_of_t</span><span class="o">&lt;</span><span class="n">Op2</span><span class="o">&amp;</span><span class="p">(</span><span class="n">projected</span><span class="o">&lt;</span><span class="n">I1</span><span class="p">,</span> <span class="n">Proj1</span><span class="o">&gt;</span><span class="p">,</span>
         <span class="n">projected</span><span class="o">&lt;</span><span class="n">I2</span><span class="p">,</span> <span class="n">Proj2</span><span class="o">&gt;</span><span class="p">)</span><span class="o">&gt;&gt;</span> <span class="n">Op1</span> <span class="o">=</span> <span class="n">plus</span><span class="o">&lt;&gt;&gt;</span>
<span class="n">requires</span>
   <span class="n">Assignable</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&amp;</span><span class="p">,</span> <span class="k">const</span> <span class="n">T</span><span class="o">&amp;&gt;</span><span class="p">()</span> <span class="o">&amp;&amp;</span>
   <span class="n">Assignable</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&amp;</span><span class="p">,</span> <span class="n">result_of_t</span><span class="o">&lt;</span><span class="n">Op1</span><span class="o">&amp;</span><span class="p">(</span><span class="n">T</span><span class="p">,</span>
      <span class="n">indirect_result_of_t</span><span class="o">&lt;</span><span class="n">Op2</span><span class="o">&amp;</span><span class="p">(</span><span class="n">projected</span><span class="o">&lt;</span><span class="n">I1</span><span class="p">,</span> <span class="n">Proj1</span><span class="o">&gt;</span><span class="p">,</span> <span class="n">projected</span><span class="o">&lt;</span><span class="n">I2</span><span class="p">,</span> <span class="n">Proj2</span><span class="o">&gt;</span><span class="p">)</span><span class="o">&gt;</span><span class="p">)</span><span class="o">&gt;&gt;</span><span class="p">()</span>
<span class="n">T</span> <span class="n">inner_product</span><span class="p">(</span><span class="n">I1</span> <span class="n">first1</span><span class="p">,</span> <span class="n">S1</span> <span class="n">last1</span><span class="p">,</span> <span class="n">I2</span> <span class="n">first2</span><span class="p">,</span> <span class="n">S2</span> <span class="n">last2</span><span class="p">,</span> <span class="n">T</span> <span class="n">init</span><span class="p">,</span> <span class="n">Op1</span> <span class="n">op1</span> <span class="o">=</span> <span class="n">Op1</span><span class="p">{},</span>
   <span class="n">Op2</span> <span class="n">op2</span> <span class="o">=</span> <span class="n">Op2</span><span class="p">{},</span> <span class="n">Proj1</span> <span class="n">proj1</span> <span class="o">=</span> <span class="n">Proj1</span><span class="p">{},</span> <span class="n">Proj2</span> <span class="n">proj2</span> <span class="o">=</span> <span class="n">Proj2</span><span class="p">{});</span>
</code></pre>
</div>

<p>Ugly. There’s lots of repetition, and overall, it’s quite difficult to reason if it’s correct. Let’s tidy that up a bit:</p>

<div class="language-cpp highlighter-rouge"><pre class="highlight"><code><span class="k">template</span> <span class="o">&lt;</span><span class="n">InputIterator</span> <span class="n">I1</span><span class="p">,</span> <span class="n">Sentinel</span><span class="o">&lt;</span><span class="n">I1</span><span class="o">&gt;</span> <span class="n">S1</span><span class="p">,</span> <span class="n">InputIterator</span> <span class="n">I2</span><span class="p">,</span> <span class="n">Sentinel</span><span class="o">&lt;</span><span class="n">I2</span><span class="o">&gt;</span> <span class="n">S2</span><span class="p">,</span>
   <span class="n">CopyConstructible</span> <span class="n">T</span><span class="p">,</span>
   <span class="k">typename</span> <span class="n">Op1</span> <span class="o">=</span> <span class="n">plus</span><span class="o">&lt;&gt;</span><span class="p">,</span> <span class="k">typename</span> <span class="n">Op2</span> <span class="o">=</span> <span class="n">multiplies</span><span class="p">,</span>
   <span class="k">typename</span> <span class="n">Proj1</span> <span class="o">=</span> <span class="n">identity</span><span class="p">,</span> <span class="k">typename</span> <span class="n">Proj2</span> <span class="o">=</span> <span class="n">identity</span><span class="p">,</span>
   <span class="k">typename</span> <span class="n">Arg1</span> <span class="o">=</span> <span class="n">projected</span><span class="o">&lt;</span><span class="n">I1</span><span class="p">,</span> <span class="n">Proj1</span><span class="o">&gt;</span><span class="p">,</span> <span class="k">typename</span> <span class="n">Arg2</span> <span class="o">=</span> <span class="n">projected</span><span class="o">&lt;</span><span class="n">I2</span><span class="p">,</span> <span class="n">Proj2</span><span class="o">&gt;</span><span class="p">,</span>
   <span class="k">typename</span> <span class="n">InnerResult</span> <span class="o">=</span> <span class="n">indirect_result_of_t</span><span class="o">&lt;</span><span class="n">Op2</span><span class="o">&amp;</span><span class="p">(</span><span class="n">Arg1</span><span class="p">,</span> <span class="n">Arg2</span><span class="p">)</span><span class="o">&gt;</span><span class="p">,</span>
   <span class="k">typename</span> <span class="n">OuterResult</span> <span class="o">=</span> <span class="n">result_of_t</span><span class="o">&lt;</span><span class="n">Op1</span><span class="o">&amp;</span><span class="p">(</span><span class="n">T</span><span class="p">,</span> <span class="n">InnerResult</span><span class="p">)</span><span class="o">&gt;&gt;</span>
<span class="n">requires</span>
   <span class="n">Assignable</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&amp;</span><span class="p">,</span> <span class="k">const</span> <span class="n">T</span><span class="o">&amp;&gt;</span><span class="p">()</span> <span class="o">&amp;&amp;</span>
   <span class="n">IndirectRegularInvocable</span><span class="o">&lt;</span><span class="n">Op2</span><span class="p">,</span> <span class="n">Arg1</span><span class="p">,</span> <span class="n">Arg2</span><span class="o">&gt;</span><span class="p">()</span> <span class="o">&amp;&amp;</span>
   <span class="n">RegularInvocable</span><span class="o">&lt;</span><span class="n">Op1</span><span class="p">,</span> <span class="n">T</span><span class="p">,</span> <span class="n">InnerResult</span><span class="o">&gt;</span><span class="p">()</span> <span class="o">&amp;&amp;</span>
   <span class="n">Assignable</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&amp;</span><span class="p">,</span> <span class="n">OuterResult</span><span class="o">&gt;</span><span class="p">()</span>
<span class="n">T</span> <span class="n">inner_product</span><span class="p">(</span><span class="n">I1</span> <span class="n">first1</span><span class="p">,</span> <span class="n">S1</span> <span class="n">last1</span><span class="p">,</span> <span class="n">I2</span> <span class="n">first2</span><span class="p">,</span> <span class="n">S2</span> <span class="n">last2</span><span class="p">,</span> <span class="n">T</span> <span class="n">init</span><span class="p">,</span> <span class="n">Op1</span> <span class="n">op1</span> <span class="o">=</span> <span class="n">Op1</span><span class="p">{},</span>
   <span class="n">Op2</span> <span class="n">op2</span> <span class="o">=</span> <span class="n">Op2</span><span class="p">{},</span> <span class="n">Proj1</span> <span class="n">proj1</span> <span class="o">=</span> <span class="n">Proj1</span><span class="p">{},</span> <span class="n">Proj2</span> <span class="n">proj2</span> <span class="o">=</span> <span class="n">Proj2</span><span class="p">{});</span>
</code></pre>
</div>

<p>That’s much easier on the eyes, and our operations are properly ordered! Sadly, we’ve introduced an opportunity for Crafty Programmer who thinks that they know better than their compiler (and library specification) to manipulate the template specialisation to allow syntactically-compatible-but-semantically-incompatible types to pass the concept check. This is an unlikely scenario, but we can’t rule it out from happening for all concept-checked functions.</p>

<h4 id="desired-outcome-1">Desired outcome<a class="anchorjs-link " href="#desired-outcome-1" aria-label="Anchor link for: desired outcome 1" data-anchorjs-icon="" style="font-style: normal; font-variant: normal; font-weight: normal; font-stretch: normal; font-size: 1em; line-height: 1; font-family: anchorjs-icons; padding-left: 0.375em;"></a></h4>

<p>It’d be great if we could do this instead:</p>

<div class="language-diff highlighter-rouge"><pre class="highlight"><code>template &lt;InputIterator I1, Sentinel&lt;I1&gt; S1, InputIterator I2, Sentinel&lt;I2&gt; S2,
   CopyConstructible T, typename Op1 = plus&lt;&gt;, typename Op2 = multiplies&lt;&gt;,
   typename Proj1 = identity, typename Proj2 = identity&gt;
requires requires {
   requires Assignable&lt;T&amp;, const T&amp;&gt;();

<span class="gi">+   using Arg1 = projected&lt;I1, Proj1&gt;;
+   using Arg2 = projected&lt;I2, Proj2&gt;;
+   using Inner_result = indirect_result_of_t&lt;Op2&amp;(Arg1, Arg2)&gt;;
+   using Outer_result = result_of_t&lt;Op1&amp;(T, InnerResult)&gt;;
</span>
   requires IndirectRegularInvocable&lt;Op2, Arg1, Arg2&gt;();
   requires RegularInvocable&lt;Op1, T, InnerResult&gt;();
   requires Assignable&lt;T&amp;, OuterResult&gt;();
}
T inner_product(I1 first1, S1 last1, I2 first2, S2 last2, T init, Op1 op1 = Op1{},
   Op2 op2 = Op2{}, Proj1 proj1 = Proj1{}, Proj2 proj2 = Proj2{});
</code></pre>
</div>

<h4 id="why-is-this-desirable-given-the-above-motivation-1">Why is this desirable, given the above motivation?<a class="anchorjs-link " href="#why-is-this-desirable-given-the-above-motivation-1" aria-label="Anchor link for: why is this desirable given the above motivation 1" data-anchorjs-icon="" style="font-style: normal; font-variant: normal; font-weight: normal; font-stretch: normal; font-size: 1em; line-height: 1; font-family: anchorjs-icons; padding-left: 0.375em;"></a></h4>

<p>Unlike the example given in our motivation, this indisputably communicates to both programmers and the compiler that <code class="highlighter-rouge">Arg1</code>, <code class="highlighter-rouge">Arg2</code>, <code class="highlighter-rouge">Inner_result</code> and <code class="highlighter-rouge">Outer_result</code> are not supposed to be changed by removing them from a position where a programmer can accidentally or deliberately provide an alternative type.</p>

<h2 id="proposals">Proposals<a class="anchorjs-link " href="#proposals" aria-label="Anchor link for: proposals" data-anchorjs-icon="" style="font-style: normal; font-variant: normal; font-weight: normal; font-stretch: normal; font-size: 1em; line-height: 1; font-family: anchorjs-icons; padding-left: 0.375em;"></a></h2>

<p>This document suggests three compounding proposals, provides minor motivations for each, and then discusses their benefits and drawbacks.</p>

<h3 id="proposal-1">Proposal 1<a class="anchorjs-link " href="#proposal-1" aria-label="Anchor link for: proposal 1" data-anchorjs-icon="" style="font-style: normal; font-variant: normal; font-weight: normal; font-stretch: normal; font-size: 1em; line-height: 1; font-family: anchorjs-icons; padding-left: 0.375em;"></a></h3>

<p>A requirements-body allows alias-declarations.</p>

<div class="language-diff highlighter-rouge"><pre class="highlight"><code>// Example 1
template &lt;class T&gt;
requires(T t) {
   typename value_type_t&lt;T&gt;;
<span class="gi">+   using value_type = value_type_t&lt;T&gt;;
</span>   {t + t} -&gt; value_type;
}
void foo(T t) {}

// Example 2
template &lt;class T&gt;
requires(T t) {
   typename value_type_t&lt;T&gt;;
<span class="gi">+   using value_type = value_type_t&lt;T&gt;;
</span>   {t + t} -&gt; value_type;
}
void foo(T t)
{
   value_type bar{}; // ill-formed, value_type not in scope
}

// Example 3
template &lt;class T&gt;
requires(T t) {
   typename value_type_t&lt;T&gt;;
<span class="gi">+   using value_type = value_type_t&lt;T&gt;;
</span>   {t + t} -&gt; value_type;
}
void foo(T t)
{
   using value_type = value_type_t&lt;T&gt;;
   value_type bar{}; // okay, value_type in scope
}
</code></pre>
</div>

<h4 id="relevant-motivation">Relevant motivation<a class="anchorjs-link " href="#relevant-motivation" aria-label="Anchor link for: relevant motivation" data-anchorjs-icon="" style="font-style: normal; font-variant: normal; font-weight: normal; font-stretch: normal; font-size: 1em; line-height: 1; font-family: anchorjs-icons; padding-left: 0.375em;"></a></h4>

<p>The key motivation for this proposal is its simplicity: an alias declared inside a <em>requirement-body</em> stays inside said <em>requirement-body</em>. Names are guaranteed not to leak into other namespaces, including function definitions and class specifications.</p>

<p>However, the author feels that this proposal, while simple, is very short sighted. A programmer that is specifying the requirements for a function or class is probably also writing said code. This proposal may simplify the verbosity of a requirements-body, but the programmer still needs to explicitly type out the type requirement and a second type alias in the function/class definition. Forcing the programmer to write out the same type (with the same name) multiple times is potentially error prone. We explore solutions to these in Proposals 2 and 3.</p>

<h4 id="implementation-status">Implementation status<a class="anchorjs-link " href="#implementation-status" aria-label="Anchor link for: implementation status" data-anchorjs-icon="" style="font-style: normal; font-variant: normal; font-weight: normal; font-stretch: normal; font-size: 1em; line-height: 1; font-family: anchorjs-icons; padding-left: 0.375em;"></a></h4>

<p>This proposal is currently being implemented using a branch from GCC trunk.</p>

<p>At present, it is possible to declare an alias inside the <em>requirement-body</em>, but the alias leaks outside of the enclosing body. This means that it isn’t possible to write such code:</p>

<div class="language-cpp highlighter-rouge"><pre class="highlight"><code><span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">T</span><span class="o">&gt;</span>
<span class="n">concept</span> <span class="kt">bool</span> <span class="n">Foo</span> <span class="o">=</span> <span class="n">requires</span> <span class="p">{</span>
   <span class="k">using</span> <span class="n">Bar</span> <span class="o">=</span> <span class="kt">double</span><span class="p">;</span>
<span class="p">};</span>

<span class="k">using</span> <span class="n">Bar</span> <span class="o">=</span> <span class="kt">int</span><span class="p">;</span> <span class="c1">// error: Bar already declared on line 3
</span></code></pre>
</div>

<p>This is under investigation, and can be found on <a href="https://github.com/cjdb/gcc">GitHub</a>.</p>

<h3 id="proposal-2">Proposal 2<a class="anchorjs-link " href="#proposal-2" aria-label="Anchor link for: proposal 2" data-anchorjs-icon="" style="font-style: normal; font-variant: normal; font-weight: normal; font-stretch: normal; font-size: 1em; line-height: 1; font-family: anchorjs-icons; padding-left: 0.375em;"></a></h3>

<p>Proposal 2 complements Proposal 1 by extending aliases declared inside the <em>requirement-body</em> to the function or class definition immediately following the body.</p>

<div class="language-diff highlighter-rouge"><pre class="highlight"><code>// Example 1
template &lt;class T&gt;
requires(T t) {
   typename value_type_t&lt;T&gt;;
   using value_type = value_type_t&lt;T&gt;;
   {t + t} -&gt; value_type;
}
void foo(T t)
{
   value_type bar{}; // ok, value_type in scope
}

// Example 2
template &lt;class T&gt;
concept bool SequenceContainer = Container&lt;X&gt; &amp;&amp; requires {
   typename value_type_t&lt;X&gt;;
   using value_type = value_type_t&lt;X&gt;;
   ...
};
template &lt;SequenceContainer T&gt;
struct Matrix {
   Matrix(initializer_list&lt;value_type&gt; l); // ill-formed: value_type not in scope
};
</code></pre>
</div>

<h4 id="relevant-motivation-1">Relevant motivation<a class="anchorjs-link " href="#relevant-motivation-1" aria-label="Anchor link for: relevant motivation 1" data-anchorjs-icon="" style="font-style: normal; font-variant: normal; font-weight: normal; font-stretch: normal; font-size: 1em; line-height: 1; font-family: anchorjs-icons; padding-left: 0.375em;"></a></h4>

<p>This is a nice addition to the original proposal, as it allows for names declared inside a <em>requirement-body</em> to be declared only once. Names are still contained outside of the whole function/class scope, so there is no global pollution. This would be great in an associative container environment, for example:</p>

<div class="language-diff highlighter-rouge"><pre class="highlight"><code>template &lt;class Key, class Value, class Compare, class A&gt;
requires requires {
   using key_type = Key;
   using mapped_type = Value;
   using value_type = pair&lt;key_type, mapped_type&gt;;
   requires Allocator&lt;A, value_type&gt;;
}
class map {
   // value_type, etc. already declared
};
</code></pre>
</div>

<p>The author foresees two drawbacks in this proposal:</p>

<ol>
  <li>Aliases convenient for the <em>requirement-body</em> but unused outside are available for accidental misuse. This is not any different to using an exposition-only template parameter, but it is a point worth considering. This could potentially be resolved by making all aliases private by default, and requiring a keyword such as export to precede the alias.</li>
  <li>The aliases in the map definition might have private access, which may not always be desirable.</li>
</ol>

<p>These drawbacks might not be compatible with the suggestion from Proposal 3 due to verbosity, and the author would like to open a discussion point.</p>

<h4 id="implementation-status-1">Implementation status<a class="anchorjs-link " href="#implementation-status-1" aria-label="Anchor link for: implementation status 1" data-anchorjs-icon="" style="font-style: normal; font-variant: normal; font-weight: normal; font-stretch: normal; font-size: 1em; line-height: 1; font-family: anchorjs-icons; padding-left: 0.375em;"></a></h4>

<p>As the first proposal is still being implemented, the technical difficulties of this proposal have not yet been assessed.</p>

<h4 id="other-thoughts">Other thoughts<a class="anchorjs-link " href="#other-thoughts" aria-label="Anchor link for: other thoughts" data-anchorjs-icon="" style="font-style: normal; font-variant: normal; font-weight: normal; font-stretch: normal; font-size: 1em; line-height: 1; font-family: anchorjs-icons; padding-left: 0.375em;"></a></h4>

<p>The author also believes that this is only half of a complete solution for the problems outlined in the initial proposal: it is still necessary to specify a <em>type-requirement</em> before using the <em>alias-declaration</em>.</p>

<h3 id="proposal-3">Proposal 3<a class="anchorjs-link " href="#proposal-3" aria-label="Anchor link for: proposal 3" data-anchorjs-icon="" style="font-style: normal; font-variant: normal; font-weight: normal; font-stretch: normal; font-size: 1em; line-height: 1; font-family: anchorjs-icons; padding-left: 0.375em;"></a></h3>

<p>Proposal 3 can be either an extension to Proposal 1 or Proposal 2, and allows a <em>type-requirement</em> to be made inline with the <em>alias-declaration</em>.</p>

<h4 id="relevant-motivation-2">Relevant motivation<a class="anchorjs-link " href="#relevant-motivation-2" aria-label="Anchor link for: relevant motivation 2" data-anchorjs-icon="" style="font-style: normal; font-variant: normal; font-weight: normal; font-stretch: normal; font-size: 1em; line-height: 1; font-family: anchorjs-icons; padding-left: 0.375em;"></a></h4>

<p>One might conclude that we can allow <em>alias-declarations</em> to immediately double as a <em>type-requirement</em>, but this doesn’t work, since the following would not be possible:</p>

<div class="language-diff highlighter-rouge"><pre class="highlight"><code>template &lt;typename T&gt;
requires requires(T t) {
   using intializer_type = initializer_list&lt;value_type_t&lt;T&gt;&gt;;
}
void foo(T t);
void bar()
{
   foo(vector&lt;int&gt;{}); // ill-formed: vector&lt;int&gt;::initializer_type doesn’t exist
}
</code></pre>
</div>

<p>The author instead proposes that an <em>alias-declaration</em> be prefixed with the <code class="highlighter-rouge">requires </code>keyword to indicate it is both an alias, and a requirement; otherwise, it is just an alias. For example,</p>

<div class="language-diff highlighter-rouge"><pre class="highlight"><code>template &lt;typename T&gt;
requires requires(T t) {
<span class="gi">+   requires using value_type = value_type_t&lt;T&gt;;
</span>   using initializer_type = initializer_list&lt;value_type&gt;;
   requires Constructible&lt;T, initializer_type&gt;();
}
void foo(T t);
void bar()
{
   foo(vector&lt;int&gt;{}); // ok: vector&lt;int&gt; satisfies the two requirements
   foo(pair&lt;int, int&gt;{}); // ill-formed: pair&lt;int, int&gt;::value_type doesn’t exist
}
</code></pre>
</div>

<p>In this example, we see that <code class="highlighter-rouge">vector</code> still conforms to the requirements outlined by <code class="highlighter-rouge">foo</code>: namely, <code class="highlighter-rouge">typename value_type_t&lt;T&gt;</code>, and <code class="highlighter-rouge">Constructible&lt;T, initializer_type&gt;</code> (for some type <code class="highlighter-rouge">initializer_type</code>). As stated previously, compatibility between this proposal and the previous proposal may be somewhat difficult.</p>

<h4 id="implementation-status-2">Implementation status<a class="anchorjs-link " href="#implementation-status-2" aria-label="Anchor link for: implementation status 2" data-anchorjs-icon="" style="font-style: normal; font-variant: normal; font-weight: normal; font-stretch: normal; font-size: 1em; line-height: 1; font-family: anchorjs-icons; padding-left: 0.375em;"></a></h4>

<p>No assessment has been made regarding technical feasibility at present.</p>

<h2 id="conclusion">Conclusion<a class="anchorjs-link " href="#conclusion" aria-label="Anchor link for: conclusion" data-anchorjs-icon="" style="font-style: normal; font-variant: normal; font-weight: normal; font-stretch: normal; font-size: 1em; line-height: 1; font-family: anchorjs-icons; padding-left: 0.375em;"></a></h2>

<p>In summary, we have looked at a proposal to allow for alias-declarations in requirement-bodies, a proposal extending the declarations to following functions and classes to reduce duplicate aliasing, and finally, a proposal that combines the aliasing and type-requirement into a single statement to further limit duplicate names.</p>

<p>Although there are some potential issues, the author remains hopeful that they can be ironed out.</p>

<h2 id="acknowledgements">Acknowledgements<a class="anchorjs-link " href="#acknowledgements" aria-label="Anchor link for: acknowledgements" data-anchorjs-icon="" style="font-style: normal; font-variant: normal; font-weight: normal; font-stretch: normal; font-size: 1em; line-height: 1; font-family: anchorjs-icons; padding-left: 0.375em;"></a></h2>

<p>Casey Carter and Eric Niebler entertained the initial idea and suggested potential alternative ways to implement this proposal, one of which became the actual implementation.</p>

<p>Tom Honermann and Casey also provided a proof reading of the document, and suggested several improvements.</p>


    </div>
    <script src="./anchor.min.js"></script>
    <script>anchors.add();</script>


</body></html>
