use_cases.html 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. <html>
  2. <head>
  3. <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
  4. <title>Use Cases</title>
  5. <link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
  6. <meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
  7. <link rel="home" href="../index.html" title="Chapter&#160;1.&#160;Boost.FunctionTypes 2.5">
  8. <link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Boost.FunctionTypes 2.5">
  9. <link rel="prev" href="introduction.html" title="Introduction">
  10. <link rel="next" href="about_tag_types.html" title="About Tag Types">
  11. </head>
  12. <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
  13. <table cellpadding="2" width="100%"><tr>
  14. <td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
  15. <td align="center"><a href="../../../../../index.html">Home</a></td>
  16. <td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
  17. <td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
  18. <td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
  19. <td align="center"><a href="../../../../../more/index.htm">More</a></td>
  20. </tr></table>
  21. <hr>
  22. <div class="spirit-nav">
  23. <a accesskey="p" href="introduction.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="about_tag_types.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
  24. </div>
  25. <div class="section">
  26. <div class="titlepage"><div><div><h2 class="title" style="clear: both">
  27. <a name="boost_functiontypes.use_cases"></a><a class="link" href="use_cases.html" title="Use Cases">Use Cases</a>
  28. </h2></div></div></div>
  29. <p>
  30. Generic libraries that accept callable arguments are common in C++. Accepting
  31. a callable argument of builin type often involves a lot of repetitive code
  32. because the accepting function is overloaded for different function arities.
  33. Further, member functions may have <code class="literal">const</code>/<code class="literal">volatile</code>-qualifiers,
  34. a function may take a variable number of (additional, POD-typed) arguments
  35. (such as <code class="literal">printf</code>) and several C++ implementations encode
  36. a calling convention with each function's type to allow calls across language
  37. or (sub-)system boundaries.
  38. </p>
  39. <pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">R</span><span class="special">&gt;</span>
  40. <span class="keyword">void</span> <span class="identifier">accept_function</span><span class="special">(</span><span class="identifier">R</span><span class="special">(*</span> <span class="identifier">func</span><span class="special">)());</span>
  41. <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">R</span><span class="special">&gt;</span>
  42. <span class="keyword">void</span> <span class="identifier">accept_function</span><span class="special">(</span><span class="identifier">R</span><span class="special">(&amp;</span> <span class="identifier">func</span><span class="special">)());</span>
  43. <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">R</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">C</span><span class="special">&gt;</span>
  44. <span class="keyword">void</span> <span class="identifier">accept_function</span><span class="special">(</span><span class="identifier">R</span><span class="special">(</span><span class="identifier">C</span><span class="special">::*</span> <span class="identifier">func</span><span class="special">)());</span>
  45. <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">R</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">C</span><span class="special">&gt;</span>
  46. <span class="keyword">void</span> <span class="identifier">accept_function</span><span class="special">(</span><span class="identifier">R</span><span class="special">(</span><span class="identifier">C</span><span class="special">::*</span> <span class="identifier">func</span><span class="special">)()</span> <span class="keyword">const</span><span class="special">);</span>
  47. <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">R</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">C</span><span class="special">&gt;</span>
  48. <span class="keyword">void</span> <span class="identifier">accept_function</span><span class="special">(</span><span class="identifier">R</span><span class="special">(</span><span class="identifier">C</span><span class="special">::*</span> <span class="identifier">func</span><span class="special">)()</span> <span class="keyword">volatile</span><span class="special">);</span>
  49. <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">R</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">C</span><span class="special">&gt;</span>
  50. <span class="keyword">void</span> <span class="identifier">accept_function</span><span class="special">(</span><span class="identifier">R</span><span class="special">(</span><span class="identifier">C</span><span class="special">::*</span> <span class="identifier">func</span><span class="special">)()</span> <span class="keyword">const</span> <span class="keyword">volatile</span><span class="special">);</span>
  51. <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">R</span><span class="special">&gt;</span>
  52. <span class="keyword">void</span> <span class="identifier">accept_function</span><span class="special">(</span><span class="identifier">R</span><span class="special">(*</span> <span class="identifier">func</span><span class="special">)(...));</span>
  53. <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">R</span><span class="special">&gt;</span>
  54. <span class="keyword">void</span> <span class="identifier">accept_function</span><span class="special">(</span><span class="identifier">R</span><span class="special">(&amp;</span> <span class="identifier">func</span><span class="special">)(...));</span>
  55. <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">R</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">C</span><span class="special">&gt;</span>
  56. <span class="keyword">void</span> <span class="identifier">accept_function</span><span class="special">(</span><span class="identifier">R</span><span class="special">(</span><span class="identifier">C</span><span class="special">::*</span> <span class="identifier">func</span><span class="special">)(...));</span>
  57. <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">R</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">C</span><span class="special">&gt;</span>
  58. <span class="keyword">void</span> <span class="identifier">accept_function</span><span class="special">(</span><span class="identifier">R</span><span class="special">(</span><span class="identifier">C</span><span class="special">::*</span> <span class="identifier">func</span><span class="special">)(...)</span> <span class="keyword">const</span><span class="special">);</span>
  59. <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">R</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">C</span><span class="special">&gt;</span>
  60. <span class="keyword">void</span> <span class="identifier">accept_function</span><span class="special">(</span><span class="identifier">R</span><span class="special">(</span><span class="identifier">C</span><span class="special">::*</span> <span class="identifier">func</span><span class="special">)(...)</span> <span class="keyword">volatile</span><span class="special">);</span>
  61. <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">R</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">C</span><span class="special">&gt;</span>
  62. <span class="keyword">void</span> <span class="identifier">accept_function</span><span class="special">(</span><span class="identifier">R</span><span class="special">(</span><span class="identifier">C</span><span class="special">::*</span> <span class="identifier">func</span><span class="special">)(...)</span> <span class="keyword">const</span> <span class="keyword">volatile</span><span class="special">);</span>
  63. <span class="comment">// ...</span>
  64. <span class="comment">// needs to be repeated for every additional function parameter</span>
  65. <span class="comment">// times the number of possible calling conventions</span>
  66. </pre>
  67. <p>
  68. The "overloading approach" obviously does not scale well: There might
  69. be several functions that accept callable arguments in one library and client
  70. code might end up using several libraries that use this pattern. On the developer
  71. side, library developers spend their time solving the same problem, working
  72. around the same portability issues, and apply similar optimizations to keep
  73. the compilation time down.
  74. </p>
  75. <p>
  76. Using Boost.FunctionTypes it is possible to write a single function template
  77. instead:
  78. </p>
  79. <pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">F</span><span class="special">&gt;</span>
  80. <span class="keyword">void</span> <span class="identifier">accept_function</span><span class="special">(</span><span class="identifier">F</span> <span class="identifier">f</span><span class="special">)</span>
  81. <span class="special">{</span>
  82. <span class="comment">// ... use Boost.FunctionTypes to analyse F</span>
  83. <span class="special">}</span>
  84. </pre>
  85. <p>
  86. The combination with a tuples library that provides an invoker component, such
  87. as <a href="../../../../fusion/index.html" target="_top">Boost.Fusion</a>, allows to
  88. build flexible callback facilities that are entirely free of repetitive code
  89. as shown by the <a href="../../../../function_types/example/interpreter.hpp" target="_top">interpreter
  90. example</a>.
  91. </p>
  92. <p>
  93. When taking the address of an overloaded function or function template, the
  94. type of the function must be known from the context the expression is used
  95. in. The code below shows three examples for choosing the <code class="literal">float(float)</code>
  96. overload of <code class="literal">std::abs</code>.
  97. </p>
  98. <pre class="programlisting"><span class="keyword">float</span> <span class="special">(*</span><span class="identifier">ptr_absf</span><span class="special">)(</span><span class="keyword">float</span><span class="special">)</span> <span class="special">=</span> <span class="special">&amp;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">abs</span><span class="special">;</span>
  99. <span class="keyword">void</span> <span class="identifier">foo</span><span class="special">(</span><span class="keyword">float</span><span class="special">(*</span><span class="identifier">func</span><span class="special">)(</span><span class="keyword">float</span><span class="special">));</span>
  100. <span class="keyword">void</span> <span class="identifier">bar</span><span class="special">()</span>
  101. <span class="special">{</span>
  102. <span class="identifier">foo</span><span class="special">(&amp;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">abs</span><span class="special">);</span>
  103. <span class="special">}</span>
  104. <span class="identifier">std</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">b</span><span class="special">,</span> <span class="identifier">e</span><span class="special">,</span> <span class="identifier">o</span><span class="special">,</span> <span class="keyword">static_cast</span><span class="special">&lt;</span><span class="keyword">float</span><span class="special">(*)(</span><span class="keyword">float</span><span class="special">)&gt;(&amp;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">abs</span><span class="special">));</span>
  105. </pre>
  106. <p>
  107. The library's type synthesis capabilities can be used to automate overload
  108. selection and instantiation of function templates. Given an overloaded function
  109. template
  110. </p>
  111. <pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">R</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">T0</span><span class="special">&gt;</span>
  112. <span class="identifier">R</span> <span class="identifier">overloaded</span><span class="special">(</span><span class="identifier">T0</span><span class="special">);</span>
  113. <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">R</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">T0</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">T1</span><span class="special">&gt;</span>
  114. <span class="identifier">R</span> <span class="identifier">overloaded</span><span class="special">(</span><span class="identifier">T0</span><span class="special">,</span><span class="identifier">T1</span><span class="special">);</span>
  115. <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">R</span><span class="special">.</span> <span class="keyword">typename</span> <span class="identifier">T0</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">T1</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">T2</span><span class="special">&gt;</span>
  116. <span class="identifier">R</span> <span class="identifier">overloaded</span><span class="special">(</span><span class="identifier">T0</span><span class="special">,</span><span class="identifier">T1</span><span class="special">,</span><span class="identifier">T2</span><span class="special">);</span>
  117. </pre>
  118. <p>
  119. we can pick any of the three overloads and instantiate the template with template
  120. arguments from a type sequence in a single expression:
  121. </p>
  122. <pre class="programlisting"><span class="keyword">static_cast</span><span class="special">&lt;</span><a class="link" href="reference/synthesis.html#boost_functiontypes.reference.synthesis.function_pointer" title="function_pointer">function_pointer</a><span class="special">&lt;</span><span class="identifier">Seq</span><span class="special">&gt;::</span><span class="identifier">type</span><span class="special">&gt;(&amp;</span> <span class="identifier">overloaded</span><span class="special">)</span>
  123. </pre>
  124. <p>
  125. This technique can be occasionally more flexible than template argument deduction
  126. from a function call because the exact types from the sequence are used to
  127. specialize the template (including possibly cv-qualified reference types and
  128. the result type). It is applied twice in the <a href="../../../../function_types/example/interface.hpp" target="_top">interface
  129. example</a>.
  130. </p>
  131. <p>
  132. Another interersting property of callable, builtin types is that they can be
  133. valid types for non-type template parameters. This way, a function can be pinpointed
  134. at compile time, allowing the compiler to eliminate the call by inlining. The
  135. <a href="../../../../function_types/example/fast_mem_fn.hpp" target="_top">fast_mem_fn example</a>
  136. exploits this characteristic and implements a potentially inlining version
  137. of <a href="../../../../bind/mem_fn.html" target="_top">boost::mem_fn</a> limited to
  138. member functions that are known at compile time.
  139. </p>
  140. </div>
  141. <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
  142. <td align="left"></td>
  143. <td align="right"><div class="copyright-footer">Copyright &#169; 2004-2007 Tobias
  144. Schwinger<p>
  145. Distributed under the Boost Software License, Version 1.0. (See accompanying
  146. file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
  147. </p>
  148. </div></td>
  149. </tr></table>
  150. <hr>
  151. <div class="spirit-nav">
  152. <a accesskey="p" href="introduction.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="about_tag_types.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
  153. </div>
  154. </body>
  155. </html>