    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: Concepts Lite in Practice</title>
        <link>https://members.accu.org/index.php/articles/2246</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>




<div class="xar-mod-head"><span class="xar-mod-title">Programming Topics + Overload Journal #133 - June 2016 </span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c65/">Programming</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c78/">Overload</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c362/">o133</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/c65-362/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/articles/c65+362/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;Concepts Lite in Practice</h1>
<p><strong>Author:</strong>&nbsp;Martin Moene</p>
<p>
<strong>Date:</strong> 02 June 2016 09:57:37 +01:00 or Thu, 02 June 2016 09:57:37 +01:00</p>
<p><strong>Summary:</strong>&nbsp;Concepts should make templates easier to use and write. Roger Orr gives a practical example to show this.</p>
<p><strong>Body:</strong>&nbsp;<p>The Concepts TS has been published and it has been implemented in gcc 6.1, released April 2016. Using concepts with gcc is as simple as adding the <code>-fconcepts</code> flag.</p>

<p>What does using concepts look like <em>in practice</em>: do we get what we hoped for? To answer that question properly we need to ask how, and why, we got here.</p>

<p>C++ is a rich language and supports polymorphic behaviour both at run-time and at compile-time. At run-time C++ uses a class hierarchy and virtual function calls to support object oriented practices where the function called depends on the run-time type of the target; at compile time templates support generic programming where the function called depends on the compile-time static type of the template arguments.</p>

<p>One major difference between these two is that the first one is tightly constrained by the inheritance hierarchy of the objects involved but the second one can be applied to <em>unrelated</em> types.</p>

<p>Run-time polymorphism is a key component in object oriented design. The function <strong>signature</strong> to use is decided at compile time based on the static type of the target object; the <strong>implementation</strong> used is based on the run-time type of the object. The rules of C++ guarantee that any object satisfying the static type will provide an implementation for the target function. This has been a fundamental part of C++ for a very long time (about as long as it has been called C++) and has been very stable â€“ it has been essentially unchanged for over 30 years</p>

<p>Compile time polymorphism has also been in the language for a very long time. The principle is to provide a â€˜templateâ€™ which enables the compiler to generate code at compile time. One of the main motivations for this was for type-safe containers; but when coupled with non-type template arguments, overloading, and tag-dispatching the result in modern C++ is very expressive. There is, I know, a range of opinions over the utility of template meta-programming and a lot of this is because it can be very hard to <strong>debug</strong>.</p>

<p>The reason for this is that templated code is fragile â€“ whether the code is valid depends on the template arguments provided by the user when the template is instantiated. While the writer of a template has (usually) tested at least one instantiation of their code, they may have made, possibly unconscious, assumptions about the template arguments that can be used with their template.</p>

<p>(Note that if there is no valid instantiation the program is ill-formed, but a diagnostic is not required â€“ it is a â€˜hard problemâ€™ to solve in general so compilers are not required to identify this in every case.)</p>

<p>Library writers currently rely on documenting their assumptions about template parameters but it is hard to get this right. Additionally, compilers don't read documentation and so the diagnosis of a compilation failure can be painful (for the user).</p>

<p>For example, consider this simple piece of code:</p>

<pre class="programlisting">  class X{};
  std::set&lt;X&gt; x;
  x.insert(X{});</pre>
  
<p>I get 50â€“100 lines of error text from this, depending on which compiler I use.</p>

<p>The fundamental problem is that Iâ€™m missing the <code>&lt;</code> operator for <code>X</code> so it does not satisfy the LessThanComparable requirement documented in the C++ standard:</p>

<p class="blockquote">Table 18 â€“ LessThanComparable requirements [lessthancomparable]</p>

<table class="journaltable">
	<tr>
		<th>Expression</th>
		<th>Return type</th>
		<th>Requirement</th>
	</tr>
	<tr>
		<td>a &lt; b</td>
		<td>convertible to bool</td>
		<td>&lt; is a strict weak ordering relation</td>
	</tr>
</table>

<p>(In a future version of C++ this simple example may become valid â€“ generation of default comparison operators may make it into the language.)</p>

<h2>Enter concepts</h2>

<p>One of the early papers on Concepts was Bjarneâ€™s paper â€˜Concept Checking â€“ A more abstract complement to type checkingâ€™ from Oct 2003 [<a href="#[N1510]">N1510</a>]. He points out that the fundamental problem that makes it hard to provide good checking for templates in C++ is that templates are not constrained, so by default <em>any</em> possible type may be used to instantiate a template.</p>

<p>As a later paper puts it ([N2081], Sep 2006) â€œ<em>Concepts introduce a type system for templates that makes templates easier to use and easier to write.</em>â€</p>

<p>Currently type checking occurs when some part of the instantiation fails, rather than when checking against the signature of the function being called. Concepts allow the programmer to provide constraints against the types of template arguments which become part of the function signature and hence should be easier to check and provide clearer diagnostics to the user.</p>

<p>The proposals went through a number of changes and enhancements during the development of C++11 (then known as C++0x) but it eventually became clear that the system being proposed was too complex and could not be nailed down in time for a delivery of C++11 in a realistic timeframe. The proposal at that time included, among other things,  concept <em>checking</em> which ensured the implementation complied with the concepts.</p>

<p>After much discussion and a number of meetings agreement was reached to provide a simplified form of concepts, so-called â€˜Concepts Liteâ€™, and to deliver this as a free-standing Technical Specification rather than initially putting it into the C++ standard itself.</p>

<p>This would give a common standard for those implementing concepts and allow time for experimentation with the feature and feedback from this would allow refinement of the proposal before it was adopted into the C++ standard itself.</p>

<h2>Building up an example</h2>

<p>Letâ€™s build up a simple example to see what can be done with the current language rules and then show what can be done with Concepts Lite.</p>

<p>Consider this simple function declaration:</p>

<pre class="programlisting">  bool check(int lhs, int rhs);</pre>
  
<p>The function takes two <code>int</code> values and the validity of calling code is decided <em>without</em> any need to see the implementation of the function.</p>

<pre class="programlisting">  int main()
  {
    int i = 1;
    int j = 2;
    return check(i, j); // Valid!
  }</pre>
  
<p>A possible function <em>definition</em> could be:</p>

<pre class="programlisting">  bool check(int lhs, int rhs) 
  { return lhs == rhs; }</pre>
  
<p>but the calling code does not need access to the implementation at compile time and the implementation can be changed without invalidating the call site.</p>

<p>Unfortunately using a single function means the following code compiles (possibly with a warning, but the code is valid C++) but is probably not doing what is expected:</p>

<pre class="programlisting">  int main()
  {
    double root10 = sqrt(10.0); // approx 3.162278
    double pi = 3.14159;        // near enough
    return check(root10, pi);   // implicit
  }                             // conversion to int</pre>

<p>If we want to check the original <code>double</code> values rather than the (truncated) <code>int</code> values, we need to generalise the code. One way is to add an overload:</p>

<pre class="programlisting">  bool check(int lhs, int rhs);
  bool check(double lhs, double rhs);
  {
    bool b1 = check(1, 2);  // works with int
    bool b2 = check(e, pi); // works with double
  }</pre>

<p>We have generalised our function to a <em>predefined</em> set of types â€“ but we need to duplicate the implementation.</p>

<p>Another approach is to use a template:</p>

<pre class="programlisting">  template &lt;typename T&gt;
  bool check(T lhs, T rhs);</pre>
  
<p>We now have only one function definition:</p>

<pre class="programlisting">  template &lt;typename T&gt;
  bool check(T lhs, T rhs) { return lhs == rhs; }</pre>
  
<p>and we have produced a template for a set of functions for an <em>unbounded</em> number of types.</p>

<pre class="programlisting">  {
    bool b1 = check(1, 2);       // works with int
    bool b2 = check(root10, pi); // works with
  }                              // double</pre>

<p>We can easily generalise further to take two <em>different</em> types:</p>

<pre class="programlisting">  template &lt;typename T, typename U&gt;
  bool check(T lhs, U rhs);</pre>
  
<p>Now, without <strong>any</strong> further changes to the implementation, the function can deal with any two types for which equality is defined.</p>

<p>As we mentioned earlier though, compilation errors are reported during the <em>instantiation</em> of the function template; for example, if we pass an <code>int</code> and the address of an <code>int</code> we see Listing 1.</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">Basic_Template_Failure.cpp: In instantiation of 
 'bool check(T&amp;&amp;, U&amp;&amp;) [with T = int&amp;; U = int*]':
... comparison between pointer and integer [-fpermissive]
 bool check(T &amp;&amp; lhs, U &amp;&amp; rhs) { return lhs == rhs; }
                                         ~~~~^~~~~</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 1</td>
	</tr>
</table>

<p>We could do better ...</p>

<h2>â€˜SFINAEâ€™</h2>

<p>When substituting possible values for template arguments the result can be invalid â€“ in this case the program itself is not invalid, but the troublesome substitution is simply removed from the overload set. This is known as â€˜substitution failure is not an errorâ€™ which abbreviates to SFINAE.</p>

<p>Use of this rule can be used for <code>enable_if</code> and other similar techniques. Listing 2 is a simple example.</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">template &lt;typename T&gt;
void f(T t, typename T::value_type u);

template &lt;typename T&gt;
void f(T t, T u);

int main()
{
   f(1, 2);  // first f() non-viable when substituting int
   std::vector&lt;int&gt; v;
   f(v, 2);  // second f() not a match as types differ
}</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 2</td>
	</tr>
</table>

<p>In the first call to <code>f()</code> the compiler tries to substitute <code>int</code> into the first template, which involves trying to form the type <code>int::value_type</code>. This is not valid, so the first template is skipped and the second one is used.</p>

<p>We can use SFINAE in our <code>check()</code> function to ensure that the equality check will be valid:</p>

<pre class="programlisting"><span class="dimmed">  template &lt;
    typename T, typename U, 
    typename = std::enable_if_t&lt;</span> is_equality_comparable <span class="dimmed">&lt;T, U&gt;::value&gt;
  &gt;
  bool check(T &amp;&amp; lhs, U &amp;&amp; rhs);</span></pre>

<p>This has the desired effect of removing the function from the overload set if the two types are not equality comparable (see Listing 3).</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">Basic_Enable_Failure.cpp:40:21: error: no matching function for call to 
 'check(int&amp;, int*)'
return check(i, &amp;j);
                  ^
Basic_Enable_Failure.cpp:34:6: note: candidate: 
 template&lt;class T, class U, class&gt; bool check(T&amp;&amp;, U&amp;&amp;)
bool check(T &amp;&amp; lhs, U &amp;&amp; rhs) { return lhs == rhs; }
     ^~~~~
Basic_Enable_Failure.cpp:34:6: note: 
  template argument deduction/substitution failed:</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 3</td>
	</tr>
</table>

<p>Notice what we do here, which is very common with this sort of technique. We have added a <em>third</em> template argument to the template, which doesnâ€™t have a name as it is not used anywhere, and given it a default value specified in terms of the arguments that we wish to constrain.</p>

<p>We do of course need to provide <code>is_equality_comparable</code>; Listing 4 is one possible implementation.</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting"><span class="dimmed">#include &lt;type_traits&gt;

template&lt;typename T, typename U, typename = void&gt;
struct </span>is_equality_comparable <span class="dimmed">: std::false_type{ };

template&lt;typename T, typename U&gt;
struct is_equality_comparable&lt;T,U,
  typename std::enable_if&lt;
    true,
    decltype(std::declval&lt;T&amp;&gt;() == std::declval&lt;U&amp;&gt;(), (void)0)
    &gt;::type
  &gt; : std::true_type
{
};</span></pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 4</td>
	</tr>
</table>

<p>While writing this is not for the faint hearted â€“ and nor is reading it â€“ this is the sort of construct that can be written once and provided in a common header. It can therefore be used without needing to investigate the implementation. Note however that, even apart from the complexity, there is a problem with the <em>disjoint</em> between the check and the expression being checked</p>

<pre class="programlisting">  decltype(std::declval&lt;T&amp;&gt;() == std::declval&lt;U&amp;&gt;())</pre>
 
<p>The expression we want to detect is <code>lhs == rhs</code> but we have to write a more complicated expression, subject to the various rules for SFINAE, which acts as a proxy for the check we actually wanted.</p>

<p>For some expressions it can be rather challenging to find an equivalent SFINAE check, and sometimes there can be subtle differences.</p>

<h2>Concepts to the rescue</h2>

<p>There are several ways we can constrain our check function with concepts. The first, and most basic way, is by adding a <code>requires</code> clause:</p>

<pre class="programlisting"><span class="dimmed">  template &lt;typename T, typename U&gt;</span>
  requires requires(T t, U u) { t == u; }<span class="dimmed">
  bool check(T &amp;&amp; lhs, U &amp;&amp; rhs);</span></pre>

<p>The function <em>declaration</em> shows the constraint using normal C++ syntax (that matches the code used in the definition.) Calling <code>check() </code>with <code>int</code> and <code>char*</code> gives this error:</p>

<pre class="programlisting">  Basic_Requires.cpp:19:6: note: constraints not satisfied
  bool check(T &amp;&amp; lhs, U &amp;&amp; rhs) { return lhs ==  rhs; }</pre>
  
<p>(Iâ€™m using the gcc 6.1 release for these examples; there are some additional changes from Andrew Sutton still to come in gcc that should further improve the error messages.)</p>

<p>Alternatively, we could define a <em>named</em> concept and use that:</p>

<pre class="programlisting"><span class="dimmed">  template&lt;typename T, typename U&gt;
  concept bool </span>Equality_comparable<span class="dimmed">() {
    return requires(T t, U u) {
      { t == u } -&gt; bool;
    };
  }</span></pre>

<p>Naming a concept has two main benefits.</p>

<ul>
	<li>The concept can be shared by multiple template declarations</li>
	<li>Naming allows us to express some of the semantic constraints on the type.</li>
</ul>

<p>We use it like this by supplying it with appropriate arguments in the declaration:</p>

<pre class="programlisting"><span class="dimmed">  template &lt;typename T, typename U&gt;</span>
  requires Equality_comparable&lt;T, U&gt;()<span class="dimmed">
  bool check(T &amp;&amp; lhs, U &amp;&amp; rhs);</span></pre>

<p>Calling <code>check()</code> with <code>int</code> and <code>char*</code> now gives us Listing 5.</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">Basic_Concept.cpp:33:29: error: 
  cannot call function 'bool check(T&amp;&amp;, U&amp;&amp;) [with T = int&amp;; U = char*&amp;]'
  return check(argc, argv[0]);

Basic_Concept.cpp:29:6: note: 
   concept 'Equality_comparable&lt;int&amp;, char*&amp;&gt;()' was not satisfied</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 5</td>
	</tr>
</table>

<p>As another alternative the concepts TS allows us to write a concept using a variable-like syntax instead of the function-like syntax used above:</p>

<pre class="programlisting"><span class="dimmed">  template&lt;typename T, typename U&gt;
  concept bool </span>Equality_comparable = <span class="dimmed">
    requires(T t, U u) {
      { t == u } -&gt; bool;
    };

  template &lt;typename T, typename U&gt;
  requires </span>Equality_comparable&lt;T, U&gt;<span class="dimmed">
  bool check(T &amp;&amp; lhs, U &amp;&amp; rhs);</span></pre>

<p>The syntax is quite similar to the function template form, except for the reduction in the number of brackets. One restriction though is that you cannot overload variable concepts. The error handling is pretty much the same:</p>

<pre class="programlisting">Basic_Variable_Concept.cpp:29:6: note: 
  concept 'Equality_comparable&lt;int&amp;, char*&amp;&gt;' was not satisfied</pre>
  
<h2>Making consistent concepts </h2>

<p>The <code>Equality_comparable</code> concept I introduced above is asymmetric as it only checks that the expression <code>t == u</code> is valid. This matches our (only!) use case, but is not suitable for use as a <em>general</em> equality concept.</p>

<p>The ranges TS defines something like this:</p>

<pre class="programlisting"><span class="dimmed">  template&lt;typename T, typename U&gt;
  concept bool </span>EqualityComparable()<span class="dimmed"> {
    return requires(T t, U u) {
      { t == u } -&gt; bool;
      { u == t } -&gt; bool;
      { t != u } -&gt; bool;
      { u != t } -&gt; bool;
    };
  }</span></pre>

<p>However, if we use this concept in our example we now have the reverse problem: you can argue our template is now <em>over</em>-constrained. Consider this simple example of trying to use <code>check()</code> with a simple user-defined class (Listing 6).</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">struct Test{
  bool operator==(Test);
};

bool foo(Test v, Test v2)
{
  return check(v, v2);
}

Basic_Concept_Failure.cpp: In function 'int main()'
Basic_Concept_Failure.cpp:39:20: error: 
  cannot call function 'bool check(T&amp;&amp;, U&amp;&amp;)' 
  return check(v, v2);
... concept 'Equality_comparable&lt;Test&amp;, Test&amp;&gt;()'</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 6</td>
	</tr>
</table>

<p>In order to call our <code>check()</code> function we have to declare, but not necessarily define, an extra operator.</p>

<pre class="programlisting"><span class="dimmed">  struct Test{
    bool operator==(Test);</span>
    bool operator!=(Test);<span class="dimmed">
  };</span></pre>
  
<p>or</p>

<pre class="programlisting">  bool operator!=(Test, Test);<span class="dimmed">
  
  bool foo(Test v, Test v2)
  {
    return check(v, v2); // Now Ok
  }</span></pre>

<p>This was a simple example as we were instantiating the template with the same type for both <code>T</code> and <code>U</code>. If the arguments to <code>check()</code> differ in type we have a little more work to do (Listing 7).</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">struct Test{
  bool operator==(int);
};

bool foo(Test v)
{
  return check(v, 0);
}

Basic_Concept_Failure2.cpp: In function 'int main()'
Basic_Concept_Failure2.cpp:39:20: error: 
  cannot call function 'bool check(T&amp;&amp;, U&amp;&amp;)' 
  return check(v, 0);
... concept 'Equality_comparable&lt;Test&amp;, int&gt;()'</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 7</td>
	</tr>
</table>

<p>In order to call our <code>check()</code> function we now have to declare <strong>three</strong> extra functions (see Listing 8).</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting"><span class="dimmed">struct Test{
  bool operator==(int);</span>
  bool operator!=(int);<span class="dimmed">
};

// These two cannot be defined in-class</span>
bool operator==(int, Test);
bool operator!=(int, Test);<span class="dimmed">

bool foo(Test v)
{
  return check(v, 0); // Ok
}</span></pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 8</td>
	</tr>
</table>

<p>Is this good or bad? Itâ€™s both, unfortunately.</p>

<p>Defining a smallish set of well-defined and â€˜completeâ€™ concepts is arguably a good idea as it encourages/enforces more consistent operator declarations for types. Stepanovâ€™s original design for the STL was based on his work in <em>Elements of Programming</em> and he defined various type attributes such as Regular and Constructible. This type of classification is a natural fit for this sort of use of concepts.</p>

<p>However, it can increase the work needed to adapt a class to comply with a concept. C++ programmers are used to providing the minimal set of methods to use a template and have a reluctance to provide more than this. Whether this is something to be encouraged is arguable.</p>

<p>The â€˜<code>requires requires</code>â€™ use is less affected by this issue as each function template has its own clause â€“ but it raises the complexity of reading <em>each</em> function declaration, and breaks DRY.</p>

<h2>Behaviour under change</h2>

<p>When using run-time polymorphism, the derived type must implement all the pure virtual methods in the base class. If a new method is added, or a signature is changed, errors are reported when the derived class is compiled and/or instantiated (depending on exactly whatâ€™s changed).</p>

<p>When the constraints for a function change, the type provided may now <em>silently</em> fail to satisfy the constraints. This may result in a compile time failure, or may result in a <em>different</em> overload of the function being selected.</p>

<h2>More complex constraints</h2>

<p>If we look at an example with a more complicated constraint we see some additional benefits of using concepts over the existing technology that uses <code>enable_if</code> or other SFINAE techniques.</p>

<p>While <code>enable_if</code> and similar techniques do provide ways to constrain function templates it can get quite complicated. One recurring problem is the ambiguity of template argument types <strong>solely</strong> constrained by <code>enable_if</code> â€“ for example, see Listing 9.</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">struct V {
  enum { int_t, float_t } m_type;

  // Constructor from 'Int' values
  template &lt;
    typename Int, 
    typename = std::enable_if_t&lt; std::is_integral&lt;Int&gt;::value&gt;
  &gt;
  V(Int) : m_type(int_t) { /* ... */ }
 
  // Constructor from 'Float' values
  template &lt;
    typename Float, 
    typename = std::enable_if_t&lt; std::is_floating_point&lt;Float&gt;::value&gt;
  &gt;
  V(Float) : m_type(float_t) { /* ... */ }
};</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 9</td>
	</tr>
</table>

<p>Unfortunately this example does <em>not</em> compile â€“ as we have two overloads of the same constructor with the same type (that of the first template argument) â€“ see Listing 10.</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">ambiguity_with_enable_if.cpp:25:5: error: 
  'template&lt;class Float, class&gt; V::V(Float)' cannot be overloaded
  V(Float) : m_type(float_t) {}
  ^
ambiguity_with_enable_if.cpp:20:5: error: 
  with 'template&lt;class Int, class&gt; V::V(Int)'
  V(Int) : m_type(int_t) {}
  ^</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 10</td>
	</tr>
</table>

<p>The compiler never gets to try overload resolution as declaring the two overloads is a syntax error. If we add a <em>second</em> argument we can resolve the ambiguity and allow overload resolution to take place; SFINAE will then remove the case(s) we do not want.</p>

<p>We can give the extra argument a default value to avoid the caller needing to be concerned with it. (Listing 11)</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">enum { int_t, float_t } m_type;

template &lt;int&gt; struct dummy { dummy(int) {} };

// Constructor from 'Int' values<span class="dimmed">
template &lt;
  typename Int, 
  typename = std::enable_if_t&lt; std::is_integral&lt;Int&gt;::value&gt;
&gt;
V(Int, </span>dummy&lt;0&gt; = 0<span class="dimmed">) : m_type(int_t) {/* ... */}</span>

// Constructor from 'Float' values
template &lt;
  typename Float, 
  typename = std::enable_if_t&lt; std::is_floating_point&lt;Float&gt;::value&gt;
&gt;
<span class="dimmed">V(Float,</span> dummy&lt;1&gt; = 0<span class="dimmed">) : m_type(float_t) {/*...*/}</span></pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 11</td>
	</tr>
</table>

<p>The additional dummy arguments are of two <em>different</em> types, <code>dummy&lt;0&gt; </code>and <code>dummy&lt;1&gt;</code>, and so we no longer have ambiguity and both functions participate in overload resolution.</p>

<p>However, this addition of dummy arguments that take no other part in the function call adds needless complexity for both the compiler and for the readers and writer of the template. We are also relying on the optimiser removing the dummy arguments.</p>

<p>Concepts are a language feature and so the solution using them is much clearer, as can be seen in Listing 12.</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting"><span class="dimmed">struct T {
  enum { int_t, float_t } m_type;

  // Constructor from 'Int' values
  template &lt;typename Int&gt;</span>
    requires std::is_integral&lt;Int&gt;::value<span class="dimmed">
  V(Int) : m_type(int_t) { /* ... */ }
 
  // Constructor from 'Float' values
  template &lt;typename Float&gt;</span>
    requires std::is_floating_point&lt;Float&gt;::value<span class="dimmed">
  V(Float) : m_type(float_t) { /* ... */ }
};</span></pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 12</td>
	</tr>
</table>

<p>There is no ambiguity here as the constraints are part of the overload resolution rules themselves and so there is no need for dummy arguments.</p>

<h2>Concept introducer syntax</h2>

<p>The concepts TS supports a â€˜concept introducerâ€™ syntax and an abbreviated syntax which I have not yet demonstrated, so letâ€™s modify the example to do so.</p>

<p>A lot of the complexity in the wording of the Concepts TS is to ensure that the specification of a constrained function using this additional syntax is equivalent to the <code>requires</code> form (Listing 13).</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting"><span class="dimmed">template &lt;typename T&gt;
concept bool Int = std::is_integral_v&lt;T&gt;;

template &lt;typename T&gt;
concept bool Float = std::is_floating_point_v&lt;T&gt;;

struct V {
  enum { int_t, float_t } m_type;

  // Constructor from 'Int' values
  template &lt;</span>Int T<span class="dimmed">&gt;
  V(T) : m_type(int_t) { /* ... */ }
 
  // Constructor from 'Float' values
  template &lt;</span>Float F<span class="dimmed">&gt;
  V(F) : m_type(float_t) { /* ... */ }
};</span></pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 13</td>
	</tr>
</table>

<p>This is syntactic sugar to avoid needing to use <code>typename</code>: </p>

<pre class="programlisting">  template &lt;Int T&gt;
  bool check(T value);</pre>
  
<p>is equivalent to:</p>

<pre class="programlisting">  template &lt;typename T&gt;
  requires Int&lt;T&gt;
  bool check(T value);</pre>

<p>The translation between the introducer syntax and that using <code>requires</code> is fairly simple and unlikely to cause confusion. Note though that, as they are equivalent, both forms can occur in the same translation unit â€“ and that the name <code>T</code> could be different.</p>

<p>It does save characters: in this case 37 vs 58. How much of a benefit this is seems to depend who you ask.</p>

<p>You can further abbreviate the syntax:</p>

<pre class="programlisting"><span class="dimmed">  struct V {
    enum { int_t, float_t } m_type;
	
    // Constructor from 'Int' values</span>
    V(Int)<span class="dimmed"> : m_type(int_t) { /* ... */ }

    // Constructor from 'Float' values</span>
    V(Float)<span class="dimmed"> : m_type(float_t) { /* ... */ }
  };</span></pre>

<p>This syntax allows the declaration of templates without needing to use <code>&lt;&gt;</code>.</p>

<p>Is this a good thing? There seem to be three main answers:</p>

<ul>
	<li>Yes</li>
	<li>No</li>
	<li>Maybe</li>
</ul>

<p>One reason why it might be troublesome is the difference that a function being a template or not makes to the lookup and argument matching rules (see Listing 14).</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">bool check(Int value);

void test(Float f)
{
  if (check(f))
  {
    // do something
  }
}</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 14</td>
	</tr>
</table>

<p>Will <code>check()</code> get called? If <code>Int</code> is a type we look for conversions on argument types that we will not look for if <code>Int</code> is a concept.</p>

<p>Additionally, whether we need access to the definition of <code>check()</code> depends on whether it is a template or not.</p>

<h2>Equivalent or functionally equivalent?</h2>

<p>What does it all mean, anyway?</p>

<pre class="programlisting">  bool check(Int value);</pre>
  
<p>This is equivalent to:</p>

<pre class="programlisting">  template &lt;Int A&gt;
  bool check(A value);</pre>
  
<p>which is itself equivalent to:</p>

<pre class="programlisting">  template &lt;typename C&gt;
  requires Int&lt;C&gt;
  bool check(C value);</pre>
  
<p>and all of these are <em>functionally</em> equivalent to:</p>

<pre class="programlisting">  template &lt;typename D&gt;
  requires std::is_integral_v&lt;D&gt;
  bool check(D value);</pre>
  
<p>The difference is that a program <em>can</em> contain two declarations of a function template that are equivalent â€“ but it is <em>not</em> valid to contain two declarations of a function template that are only functionally equivalent. There are additional rules defining the finer details of equivalence in the concepts TS (or [<a href="#[N4335]">N4335</a>]).</p>

<h2>Restrictions on the concept introducer syntax</h2>

<pre class="programlisting">  bool check(Int value, Int other);</pre>
  
<p>This is equivalent to:</p>

<pre class="programlisting">  bool check(T value, T other);</pre>

<p>Note that the two variables will always have the <strong>same</strong> type â€“ we cannot use the short form syntax (there were some very tentative proposals, but nothing was accepted) to replace:</p>

<pre class="programlisting">  template &lt;Int T, Int U&gt;
  bool check(T value, U other);</pre>

<h2>auto templates</h2>

<p>The concepts TS also allows using <code>auto</code> to introduce an unconstrained template parameter (Listing 15).</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">bool check(auto value);

void test(Float f)
{
  if (check(f))
  {
    // do something
  }
}</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 15</td>
	</tr>
</table>

<p>I see this as less problematic than the constrained case â€“ it mirrors the existing use of <code>auto</code> for declaring a polymorphic lambda. There is no ambiguity in the mind of the reader about whether or not the function so declared is a template, the use of <code>auto</code> means it must be a template and so no further context is needed.</p>

<p>While â€˜Concepts Liteâ€™ is not part of C++17 (see, for example, [<a href="#[Honermann]">Honermann</a>] for more on this...) this part of the TS does stand a little apart from the rest and I for one would have been happy to accept this into C++17 as a separate proposal; sadly this hasnâ€™t been proposed yet and the departure gate for C++17 is probably closed for that option.</p>

<h2>Summary</h2>

<p>Concepts do seem to be significantly simpler to read and write than the current alternatives.</p>

<p>It does seem to me that it delivers better compiler errors for users; while Iâ€™m sure it is possible to find counter-examples I expect them to be rarer.</p>

<p>It is easier to constrain functions, for writers, without requiring complex and sometimes fragile meta-programming trickery. Concepts also express intent in code rather than by inference, in documentation, or in comments.</p>

<p>Using concepts does have the potential of under or over constraining. If we under-constrain types that match, the concepts fail when the template is instantiated, and if we over-constrain, we restrict the set of allowable types further than we needed.</p>

<p>The syntax is slightly awkward â€“ this is my biggest issue with the current wording in the TS.</p>

<ul>
	<li><code>template &lt;typename T&gt; requires requires(T t) {â€¦}</code>
		<p>â€˜<code>requires requires</code>â€™ â€“ can we be serious? </p></li>

	<li><code>concept bool x = requires(...) {}</code>
		<p>the type <em>must</em> be specified and <em>must</em> be <code>bool</code></p></li>

	<li>supporting the variable form, in addition to the function form, seems to be unnecessary</li>
</ul>

<p>I am not persuaded that we need the concept introducer syntax. While it reduces the number of symbols in the code I am not sure that this actually <em>simplifies</em> things or merely hides away complexity that we do need to know about.</p>

<p>Now is the time for C++ programmers to <strong>use</strong> concepts and to provide feedback to the standards body. With the recent release of gcc 6.1 doing this has become easier.</p>

<h2>References</h2>

<p class="bibliomixed"><a id="[Honermann]"></a>[Honermann]  <a href="http://honermann.net/blog/?p=3">http://honermann.net/blog/?p=3</a> (â€˜Why concepts didnâ€™t make it into C++17â€™)</p>

<p class="bibliomixed"><a id="[N1510]"></a>[N1510]  <a href="http://www.stroustrup.com/n1510-concept-checking.pdf">http://www.stroustrup.com/n1510-concept-checking.pdf</a></p>

<p class="bibliomixed"><a id="[N2018]"></a>[N2018]  <a href="http://open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2081.pdf">http://open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2081.pdf</a></p>

<p class="bibliomixed"><a id="[N4335]"></a>[N4335]  <a href="http://open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4335.html">http://open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4335.html</a> (pre-publication concepts working paper)</p>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
