Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Disclaimer: I wasn't able to successfully use BCCL within the last 30 minutes even though I had Boost installed already. The example you see below looks OK according to the BCCL documentation of Boost 1.37 but didn't work. I guess this counts as disadvantage.</p> <p>With BCCL you only get something like static assertions whereas the core language concept feature provides full modular type checking and is able to prevent some function template from participating in overload resolution. With native concepts the body of a constrained template can be checked immediately by the compiler whereas BCCL doesn't make the compiler check anything in that respect. You have to manually instantiate your template with "arche type" parameters to see if the template uses any operations that are not available (for example, operator-- on forward iterators).</p> <p>As for overload resolution here's an example:</p> <pre><code>template&lt;typename Iter&gt; void foo(Iter,Iter) { BOOST_CONCEPT_ASSERT((RandomAccessIterator&lt;Iter&gt;)); } void foo(long, int); int main() { foo(2,3); // compile-time error } </code></pre> <p>The template is a better match because the non-template requires a conversion from int to long. But instantiation fails because int is not an iterator. You get a nice error message explaining it but that's not very satisfying, is it? With native concepts you could have written</p> <pre><code>template&lt;typename Iter&gt; requires RandomAccessIterator&lt;Iter&gt; void foo(Iter,Iter) {} void foo(long, int); int main() { foo(2,3); // OK, picks non-template foo } </code></pre> <p>Here, the function template will not take part in overload resolution because the requirement for T=int is not satisfied. Great!</p> <p>We still get to constrain function templates with the SFINAE trick. C++0x extends SFINAE to expressions and together with decltype and default template arguments for function templates we can write</p> <pre><code>template&lt;typename T&gt; T&amp;&amp; make(); template&lt;typename Iter, class = decltype( *make&lt;Iter&gt;() )&gt; void foo(Iter,Iter) {} void foo(long, int); int main() { foo(2,3); // OK, picks non-template foo } </code></pre> <p>In this case, template argument deduction will fail <em>silently</em> because the compiler doesn't know what the type of the expression &#8727;make&lt;Iter&gt;() is supposed to be (we can't dereference an int). With a bit of template metaprogramming and some macros we can get pretty close to imposing arbitrary structural constraints on template parameters <em>in a readable way</em>. Here's what it might look like assuming appropriate definitions for REQUIRES and RandomAccessIterator:</p> <pre><code>template &lt;typename Iter REQUIRES( RandomAccessIterator&lt;Iter&gt; ) &gt; void foo(Iter,Iter) {} </code></pre> <p>HTH, S</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload