motivation.html 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. <html>
  2. <head>
  3. <title>motivation.html</title>
  4. <link rel="stylesheet" type="text/css" href="../styles.css">
  5. </head>
  6. <body>
  7. <h4>Motivation</h4>
  8. <div>
  9. The C++ function and template parameter lists are special syntactic constructs, and it is impossible to directly
  10. manipulate or generate them using C++ constructs.&nbsp;
  11. This leads to unnecessary code repetition.
  12. </div>
  13. <div>
  14. Consider the implementation of the <code>is_function&lt;&gt;</code> metafunction is Boost.&nbsp;
  15. The implementation uses an overloaded <code>is_function_tester()</code> function that is used for testing if a type is convertible
  16. to a pointer to a function.&nbsp;
  17. Because of the special treatment of parameter lists, it is not possible to directly match a function with an arbitrary parameter list.&nbsp;
  18. Instead, the <code>is_function_tester()</code> must be overloaded for every distinct number of parameters that is to be supported.&nbsp;
  19. For example:
  20. </div>
  21. <div class="code"><pre>
  22. template&lt;class R&gt;
  23. yes_type is_function_tester(R (*)());
  24. template&lt;class R, class A0&gt;
  25. yes_type is_function_tester(R (*)(A0));
  26. template&lt;class R, class A0, class A1&gt;
  27. yes_type is_function_tester(R (*)(A0, A1));
  28. template&lt;class R, class A0, class A1, class A2&gt;
  29. yes_type is_function_tester(R (*)(A0, A1, A2));
  30. // ...
  31. </pre></div>
  32. <div>
  33. The need for this kind of repetition occurs particularly frequently while implementing generic components or metaprogramming facilities,
  34. but the need also manifests itself in many far simpler situations.
  35. </div>
  36. <h4>Typical Solutions</h4>
  37. <div>
  38. Typically the repetition is done manually.&nbsp;
  39. Manual code repetition is highly unproductive, but sometimes more readable to the untrained eye.
  40. </div>
  41. <div>
  42. Another solution is to write an external program for generating the repeated code or use some other extra linguistic means such as a smart editor.&nbsp;
  43. Unfortunately, using external code generators has many disadvantages:
  44. <ul>
  45. <li>Writing the generator takes time.&nbsp; (This could be helped by using a standard generator.)</li>
  46. <li>It is no longer productive to manipulate C++ code directly.</li>
  47. <li>Invoking the generator may be difficult.</li>
  48. <li>Automating the invocation of the generator can be difficult in certain environments.&nbsp; (Automatic invocation is desirable for active libraries.)</li>
  49. <li>Porting and distributing the generator may be difficult or simply takes precious time.</li>
  50. </ul>
  51. </div>
  52. <h4>What about the preprocessor?</h4>
  53. <div>
  54. Because C++ comes with a preprocessor, one would assume that it would support these kinds of needs directly.&nbsp;
  55. Using the preprocessor in this case is highly desirable because:
  56. <ul>
  57. <li>The preprocessor is highly portable.</li>
  58. <li>The preprocessor is automatically invoked as part of the compilation process.</li>
  59. <li>Preprocessor metacode can be directly embedded into the C++ source code.</li>
  60. <li>Compilers generally allow viewing or outputting the preprocessed code, which can be used for debugging or to copy and paste the generated code.</li>
  61. </ul>
  62. </div>
  63. <div>
  64. Most unfortunately, the preprocessor is a very low level preprocessor that specifically does not support repetition or recursive macros.&nbsp;
  65. Library support is needed!
  66. </div>
  67. <div>
  68. <i>For detailed information on the capabilities and limitations of the preprocessor, please refer to the C++ standard <a href="../bibliography.html#std">[Std]</a>.</i>
  69. </div>
  70. <h4>The Motivation Example Revisited</h4>
  71. <div>
  72. Using the primitives of the preprocessor library, the <code>is_function_tester()</code>'s could be implemented like this:
  73. </div>
  74. <div class="code"><pre>
  75. #include &lt;boost/preprocessor/arithmetic/inc.hpp&gt;
  76. #include &lt;boost/preprocessor/punctuation/comma_if.hpp&gt;
  77. #include &lt;boost/preprocessor/repetition.hpp&gt;
  78. #ifndef MAX_IS_FUNCTION_TESTER_PARAMS
  79. #define MAX_IS_FUNCTION_TESTER_PARAMS 15
  80. #endif
  81. #define IS_FUNCTION_TESTER(Z, N, _) \
  82. template&lt;class R BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_PARAMS(N, class A)&gt; \
  83. yes_type is_function_tester(R (*)(BOOST_PP_ENUM_PARAMS(N, A))); \
  84. /**/
  85. BOOST_PP_REPEAT(BOOST_PP_INC(MAX_IS_FUNCTION_TESTER_PARAMS), IS_FUNCTION_TESTER, _)
  86. #undef IS_FUNCTION_TESTER
  87. </pre></div>
  88. <div>
  89. In order to change the maximum number of function parameters supported, you now simply change the <code>MAX_IS_FUNCTION_TESTER_PARAMS</code> definition and recompile.
  90. </div>
  91. <hr size="1">
  92. <div style="margin-left: 0px;">
  93. <i>© Copyright <a href="http://www.housemarque.com" target="_top">Housemarque Oy</a> 2002</i>
  94. </div>
  95. <div style="margin-left: 0px;">
  96. Permission to copy, use, modify, sell and distribute this document is granted provided this copyright notice appears in all copies.&nbsp;
  97. This document is provided "as is" without express or implied warranty and with no claim as to its suitability for any purpose.
  98. </div>
  99. <hr size="1">
  100. <div style="margin-left: 0px;">
  101. <i>© Copyright <a href="http://www.housemarque.com" target="_top">Housemarque Oy</a> 2002</i>
  102. </br><i>© Copyright Paul Mensonides 2002</i>
  103. </div>
  104. <div style="margin-left: 0px;">
  105. <p><small>Distributed under the Boost Software License, Version 1.0. (See
  106. accompanying file <a href="../../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or
  107. copy at <a href=
  108. "http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</small></p>
  109. </div>
  110. </body>
  111. </html>