concept_check.htm 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  2. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  3. <html xmlns="http://www.w3.org/1999/xhtml">
  4. <!-- Copyright (c) 2000 Jeremy Siek and Andrew Lumsdaine, 2007 David Abrahams -->
  5. <!-- Distributed under the Boost -->
  6. <!-- Software License, Version 1.0. (See accompanying -->
  7. <!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
  8. <head>
  9. <meta name="generator" content=
  10. "HTML Tidy for Linux/x86 (vers 1 September 2005), see www.w3.org" />
  11. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  12. <title>Concept Check Library</title>
  13. <link rel="stylesheet" href="../../rst.css" type="text/css" />
  14. </head>
  15. <body bgcolor="#FFFFFF" link="#0000EE" text="#000000" vlink="#551A8B" alink=
  16. "#FF0000">
  17. <img src="../../boost.png" alt="C++ Boost" width="277" height=
  18. "86" /><br clear="none" />
  19. <h1>The Boost Concept Check Library (BCCL)</h1>
  20. <blockquote>
  21. The Concept Check library allows one to add explicit statement and
  22. checking of <a href=
  23. "http://www.boost.org/more/generic_programming.html#concept">concepts</a> in the style
  24. of the <a href=
  25. "http://www.generic-programming.org/languages/conceptcpp/specification/">proposed
  26. C++ language extension</a>.
  27. </blockquote>
  28. <h2><a name="sec:concept-checking" id="sec:concept-checking"></a>Synopsis</a></h2>
  29. <p>Generic programming in C++ is characterized by the use of template
  30. parameters to represent abstract data types (or “<a href=
  31. "http://www.boost.org/more/generic_programming.html#concept">concepts</a>”). However, the
  32. C++ language itself does not provide a mechanism for the writer of a class
  33. or function template to explicitly state the concept that the user-supplied
  34. template argument should model (or conform to). Template parameters are
  35. commonly named after the concept they're required to model as a hint to the
  36. user, and to make the concept requirements explicit in code. However, the
  37. compiler doesn't treat these special names specially: a parameter named
  38. <code>RandomAccessIterator</code> is no different to the compiler than one
  39. named <code>T</code>. Furthermore,</p>
  40. <ul>
  41. <li>Compiler error messages resulting from incorrect template arguments
  42. can be particularly difficult to decipher. Often times the error does not
  43. point to the location of the template call-site, but instead exposes the
  44. internals of the template, which the user should never have to see.</li>
  45. <li>Without checking from the compiler, the documented requirements are
  46. oftentimes vague, incorrect, or nonexistent, so a user cannot know
  47. exactly what kind of arguments are expected.</li>
  48. <li>The documented concept requirements may not fully <i>cover</i> the
  49. needs of the actual template, meaning the user could get a compiler error
  50. even though the supplied template arguments meet the documented
  51. requirements.</li>
  52. <li>The documented concept requirements may be too stringent, requiring
  53. more than is really needed by the template.</li>
  54. <li>Concept names in code may drift out-of-sync with the documented
  55. requirements.</li>
  56. </ul><p>The Boost Concept Checking Library provides:
  57. <ul>
  58. <li>A mechanism for inserting compile-time checks on template parameters
  59. at their point of use.</li>
  60. <li>A framework for specifying concept requirements through concept
  61. checking classes.</li>
  62. <li>A mechanism for verifying that concept requirements cover the
  63. template.</li>
  64. <li>A suite of concept checking classes and archetype classes that match
  65. the concept requirements in the C++ Standard Library.</li>
  66. <li>An alternative to the use of traits classes for accessing associated
  67. types that mirrors the syntax proposed for the next C++ standard.</li>
  68. </ul><p>The mechanisms use standard C++ and introduce no run-time overhead.
  69. The main cost of using the mechanism is in compile-time.</p>
  70. <p><strong>Every programmer writing class or function templates ought to
  71. make concept checking a normal part of their code writing routine.</strong>
  72. A concept check should be inserted for each template parameter in a
  73. component's public interface. If the concept is one of the ones from the
  74. Standard Library, then simply use the matching concept checking class in
  75. the BCCL. If not, then write a new concept checking class - after all, they
  76. are typically only a few lines long. For new concepts, a matching archetype
  77. class should also be created, which is a minimal skeleton-implementation of
  78. the concept</p>
  79. <p>The documentation is organized into the following sections.</p>
  80. <ol>
  81. <li><a href="#introduction">Introduction</a></li>
  82. <li><a href="#motivating-example">Motivating Example</a></li>
  83. <li><a href="#history">History</a></li>
  84. <li><a href="#publications">Publications</a></li>
  85. <li><a href="#acknowledgements">Acknowledgements</a></li>
  86. <li><a href="./using_concept_check.htm">Using Concept Checks</a></li>
  87. <li><a href="creating_concepts.htm">Creating Concept Checking
  88. Classes</a></li>
  89. <li><a href="./concept_covering.htm">Concept Covering and
  90. Archetypes</a></li>
  91. <li><a href="./prog_with_concepts.htm">Programming With Concepts</a></li>
  92. <li><a href="./implementation.htm">Implementation</a></li>
  93. <li><a href="./reference.htm">Reference</a></li>
  94. </ol>
  95. <p><a href="http://www.boost.org/people/jeremy_siek.htm">Jeremy Siek</a> contributed this
  96. library. <a href="http://www.boost.org/people/beman_dawes.html">Beman Dawes</a> managed
  97. the formal review. <a href="http://www.boost.org/people/dave_abrahams.htm">Dave
  98. Abrahams</a> contributed a rewrite that updated syntax to be more
  99. compatible with proposed syntax for concept support the C++ core
  100. language.</p>
  101. <h2><a name="introduction" id="introduction">Introduction</a></h2><p>A
  102. <i>concept</i> is a set of requirements (valid expressions, associated
  103. types, semantic invariants, complexity guarantees, etc.) that a type must
  104. fulfill to be correctly used as arguments in a call to a generic algorithm.
  105. In C++, concepts are represented by formal template parameters to function
  106. templates (generic algorithms). However, C++ has no explicit mechanism for
  107. representing concepts—template parameters are merely placeholders. By
  108. convention, these parameters are given names corresponding to the concept
  109. that is required, but a C++ compiler does not enforce compliance to the
  110. concept when the template parameter is bound to an actual type.
  111. <p>Naturally, if a generic algorithm is invoked with a type that does not
  112. fulfill at least the syntactic requirements of the concept, a compile-time
  113. error will occur. However, this error will not <i>per se</i> reflect the
  114. fact that the type did not meet all of the requirements of the concept.
  115. Rather, the error may occur deep inside the instantiation hierarchy at the
  116. point where an expression is not valid for the type, or where a presumed
  117. associated type is not available. The resulting error messages are largely
  118. uninformative and basically impenetrable.</p>
  119. <p>What is required is a mechanism for enforcing
  120. “concept safety” at (or close to) the point
  121. of instantiation. The Boost Concept Checking Library uses some standard C++
  122. constructs to enforce early concept compliance and that provides more
  123. informative error messages upon non-compliance.</p>
  124. <p>Note that this technique only addresses the syntactic requirements of
  125. concepts (the valid expressions and associated types). We do not address
  126. the semantic invariants or complexity guarantees, which are also part of
  127. concept requirements..</p>
  128. <h2><a name="motivating-example" id="motivating-example">Motivating
  129. Example</a></h2>
  130. <p>We present a simple example to illustrate incorrect usage of a template
  131. library and the resulting error messages. In the code below, the generic
  132. <tt>std::stable_sort()</tt> algorithm from the Standard Template Library
  133. (STL)[<a href="bibliography.htm#austern99:_gener_progr_stl">3</a>, <a href=
  134. "bibliography.htm#IB-H965502">4</a>,<a href=
  135. "bibliography.htm#stepa.lee-1994:the.s:TR">5</a>] is applied to a linked
  136. list.</p>
  137. <pre>
  138. <a href="./bad_error_eg.cpp">bad_error_eg.cpp</a>:
  139. <font color="gray">1</font> #include &lt;vector&gt;
  140. <font color="gray">2</font color="gray"> #include &lt;complex&gt;
  141. <font color="gray">3</font color="gray"> #include &lt;algorithm&gt;
  142. <font color="gray">4</font color="gray">
  143. <font color="gray">5</font color="gray"> int main()
  144. <font color="gray">6</font color="gray"> {
  145. <font color="gray">7</font color="gray"> std::vector&lt;std::complex&lt;float&gt; &gt; v;
  146. <font color="gray">8</font color="gray"> std::stable_sort(v.begin(), v.end());
  147. <font color="gray">9</font color="gray"> }
  148. </pre>
  149. <p>Here, the <tt>std::stable_sort()</tt> algorithm is prototyped as
  150. follows:</p>
  151. <pre>
  152. template &lt;class RandomAccessIterator&gt;
  153. void stable_sort(RandomAccessIterator first, RandomAccessIterator last);
  154. </pre>
  155. <p>Attempting to compile this code with Gnu C++ produces the following
  156. compiler error:</p>
  157. <pre>
  158. /usr/include/c++/4.1.2/bits/stl_algo.h: In function ‘void std::
  159. __insertion_sort(_RandomAccessIterator, _RandomAccessIterator) [with
  160. _RandomAccessIterator = __gnu_cxx::__normal_iterator&lt;std::complex&lt;float
  161. &gt;*, std::vector&lt;std::complex&lt;float&gt;, std::allocator&lt;std::complex&lt;
  162. float&gt; &gt; &gt; &gt;]’:
  163. /usr/include/c++/4.1.2/bits/stl_algo.h:3066: instantiated from ‘void
  164. std::__inplace_stable_sort(_RandomAccessIterator,
  165. _RandomAccessIterator) [with _RandomAccessIterator = __gnu_cxx::
  166. __normal_iterator&lt;std::complex&lt;float&gt;*, std::vector&lt;std::complex&lt;
  167. float&gt;, std::allocator&lt;std::complex&lt;float&gt; &gt; &gt; &gt;]’
  168. /usr/include/c++/4.1.2/bits/stl_algo.h:3776: instantiated from ‘void
  169. std::stable_sort(_RandomAccessIterator, _RandomAccessIterator) [with
  170. _RandomAccessIterator = __gnu_cxx::__normal_iterator&lt;std::complex&lt;float
  171. &gt;*, std::vector&lt;std::complex&lt;float&gt;, std::allocator&lt;std::complex&lt;
  172. float&gt; &gt; &gt; &gt;]’
  173. bad_error_eg.cpp:8: instantiated from here
  174. /usr/include/c++/4.1.2/bits/stl_algo.h:2277: error: no match for
  175. ‘operator&lt;’ in ‘__val &lt; __first. __gnu_cxx::__normal_iterator&lt;
  176. _Iterator, _Container&gt;::operator* [with _Iterator = std::complex&lt;float
  177. &gt;*, _Container = std::vector&lt;std::complex&lt;float&gt;, std::allocator&lt;
  178. std::complex&lt;float&gt; &gt; &gt;]()’
  179. </pre>
  180. <p>In this case, the fundamental error is
  181. that <tt>std:complex&lt;float&gt;</tt> does not model the <a href=
  182. "http://www.boost.org/sgi/stl/LessThanComparable.html">LessThanComparable</a>
  183. concept. Unfortunately, there is nothing in the error message to
  184. indicate that to the user.</p>
  185. <p>The error may be obvious to a C++ programmer having enough
  186. experience with template libraries, but there are several reasons
  187. why this message could be hard for the uninitiated to
  188. understand:</p>
  189. <ol>
  190. <li>There is no textual correlation between the error message and the
  191. documented requirements for <tt>std::stable_sort()</tt> and for <a href=
  192. "http://www.boost.org/sgi/stl/LessThanComparable.html">LessThanComparable</a>.</li>
  193. <li>The error message is overly long, listing functions internal
  194. to the STL (e.g. <code>__insertion_sort</code>) that the user
  195. does not (and should not!) know or care about.</li>
  196. <li>With so many internal library functions listed in the error message,
  197. the programmer could easily infer that the problem is in the library,
  198. rather than in his or her own code.</li>
  199. </ol>
  200. <p>The following is an example of what we might expect from a more
  201. informative message (and is in fact what the Boost Concept Checking Library
  202. produces):</p>
  203. <pre>
  204. boost/concept_check.hpp: In destructor ‘boost::LessThanComparable&lt;TT&gt;::~
  205. LessThanComparable() [with TT = std::complex&lt;float&gt;]’:
  206. boost/concept/detail/general.hpp:29: instantiated from ‘static void boost::
  207. concepts::requirement&lt;Model&gt;::failed() [with Model = boost::
  208. LessThanComparable&lt;std::complex&lt;float&gt; &gt;]’
  209. boost/concept/requires.hpp:30: instantiated from ‘boost::_requires_&lt;void
  210. (*)(boost::LessThanComparable&lt;std::complex&lt;float&gt; &gt;)&gt;’
  211. bad_error_eg.cpp:8: instantiated from here
  212. boost/concept_check.hpp:236: error: no match for ‘operator&lt;’ in ‘((boost::
  213. LessThanComparable&lt;std::complex&lt;float&gt; &gt;*)this)-&gt;boost::
  214. LessThanComparable&lt;std::complex&lt;float&gt; &gt;::a &lt; ((boost::
  215. LessThanComparable&lt;std::complex&lt;float&gt; &gt;*)this)-&gt;boost::
  216. LessThanComparable&lt;std::complex&lt;float&gt; &gt;::b’
  217. </pre>
  218. <p>This message rectifies several of the shortcomings of the standard error
  219. messages.</p>
  220. <ul>
  221. <li>The message refers explicitly to concepts that the user can look up
  222. in the STL documentation (<a href=
  223. "http://www.boost.org/sgi/stl/LessThanComparable.html">LessThanComparable</a>).</li>
  224. <li>The error message is now much shorter and does not reveal
  225. internal STL functions, nor indeed does it even point
  226. to <code>std::stable_sort</code>.</li>
  227. <li>The presence of <tt>concept_check.hpp</tt> in the error message
  228. alerts the user to the fact that the error lies in the user code and not
  229. in the library implementation.</li>
  230. </ul>
  231. <h2><a name="history" id="history">History</a></h2>
  232. <p>The first version of this concept checking system was developed
  233. by Jeremy Siek while working at SGI in their C++ compiler and
  234. library group. That version is now part of the SGI STL
  235. distribution. The system originally introduced as the boost concept
  236. checking library differs from concept checking in the SGI STL in
  237. that the definition of concept checking classes was greatly
  238. simplified, at the price of less helpful verbiage in the error
  239. messages. In 2006 the system was rewritten (preserving backward
  240. compatibility) by Dave Abrahams to be easier to use, more similar to
  241. the proposed concept support the C++ core language, and to give
  242. better error messages.
  243. </p>
  244. <h2><a name="publications" id="publications">Publications</a></h2>
  245. <ul>
  246. <li><a href="http://www.oonumerics.org/tmpw00/">C++ Template Workshop
  247. 2000</a>, Concept Checking</li>
  248. </ul>
  249. <h2><a name="acknowledgements" id=
  250. "acknowledgements">Acknowledgements</a></h2><p>The idea to use function
  251. pointers to cause instantiation is due to Alexander Stepanov. We are not sure
  252. of the origin of the idea to use expressions to do up-front checking of
  253. templates, but it did appear in D&amp;E[ <a href=
  254. "bibliography.htm#stroustrup94:_design_evolution">2</a>]. Thanks to Matt
  255. Austern for his excellent documentation and organization of the STL
  256. concepts, upon which these concept checks are based. Thanks to Boost
  257. members for helpful comments and reviews.
  258. <p><a href="./using_concept_check.htm">Next: Using Concept
  259. Checks</a><br /></p>
  260. <hr />
  261. <table>
  262. <tr valign="top">
  263. <td nowrap="nowrap">Copyright &copy; 2000</td>
  264. <td><a href="http://www.boost.org/people/jeremy_siek.htm">Jeremy Siek</a>(<a href=
  265. "mailto:jsiek@osl.iu.edu">jsiek@osl.iu.edu</a>) Andrew
  266. Lumsdaine(<a href="mailto:lums@osl.iu.edu">lums@osl.iu.edu</a>),
  267. 2007 <a href="mailto:dave@boost-consulting.com">David Abrahams</a>.
  268. </td>
  269. </tr>
  270. </table>
  271. </body>
  272. </html>