in_place_factories.html 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. <html>
  2. <head>
  3. <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
  4. <title>In-Place Factories</title>
  5. <link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
  6. <meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
  7. <link rel="home" href="../index.html" title="Chapter&#160;1.&#160;Boost.Optional">
  8. <link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Boost.Optional">
  9. <link rel="prev" href="detailed_semantics.html" title="Detailed Semantics">
  10. <link rel="next" href="a_note_about_optional_bool_.html" title="A note about optional&lt;bool&gt;">
  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="detailed_semantics.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="a_note_about_optional_bool_.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_optional.in_place_factories"></a><a class="link" href="in_place_factories.html" title="In-Place Factories">In-Place Factories</a>
  28. </h2></div></div></div>
  29. <p>
  30. One of the typical problems with wrappers and containers is that their interfaces
  31. usually provide an operation to initialize or assign the contained object as
  32. a copy of some other object. This not only requires the underlying type to
  33. be <a href="../../../../utility/CopyConstructible.html" target="_top">Copy Constructible</a>,
  34. but also requires the existence of a fully constructed object, often temporary,
  35. just to follow the copy from:
  36. </p>
  37. <pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">X</span>
  38. <span class="special">{</span>
  39. <span class="identifier">X</span> <span class="special">(</span> <span class="keyword">int</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">)</span> <span class="special">;</span>
  40. <span class="special">}</span> <span class="special">;</span>
  41. <span class="keyword">class</span> <span class="identifier">W</span>
  42. <span class="special">{</span>
  43. <span class="identifier">X</span> <span class="identifier">wrapped_</span> <span class="special">;</span>
  44. <span class="keyword">public</span><span class="special">:</span>
  45. <span class="identifier">W</span> <span class="special">(</span> <span class="identifier">X</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">x</span> <span class="special">)</span> <span class="special">:</span> <span class="identifier">wrapped_</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span> <span class="special">{}</span>
  46. <span class="special">}</span> <span class="special">;</span>
  47. <span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
  48. <span class="special">{</span>
  49. <span class="comment">// Temporary object created.</span>
  50. <span class="identifier">W</span> <span class="special">(</span> <span class="identifier">X</span><span class="special">(</span><span class="number">123</span><span class="special">,</span><span class="string">"hello"</span><span class="special">)</span> <span class="special">)</span> <span class="special">;</span>
  51. <span class="special">}</span>
  52. </pre>
  53. <p>
  54. A solution to this problem is to support direct construction of the contained
  55. object right in the container's storage. In this scheme, the user only needs
  56. to supply the arguments to the constructor to use in the wrapped object construction.
  57. </p>
  58. <pre class="programlisting"><span class="keyword">class</span> <span class="identifier">W</span>
  59. <span class="special">{</span>
  60. <span class="identifier">X</span> <span class="identifier">wrapped_</span> <span class="special">;</span>
  61. <span class="keyword">public</span><span class="special">:</span>
  62. <span class="identifier">W</span> <span class="special">(</span> <span class="identifier">X</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">x</span> <span class="special">)</span> <span class="special">:</span> <span class="identifier">wrapped_</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span> <span class="special">{}</span>
  63. <span class="identifier">W</span> <span class="special">(</span> <span class="keyword">int</span> <span class="identifier">a0</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">a1</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">wrapped_</span><span class="special">(</span><span class="identifier">a0</span><span class="special">,</span><span class="identifier">a1</span><span class="special">)</span> <span class="special">{}</span>
  64. <span class="special">}</span> <span class="special">;</span>
  65. <span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
  66. <span class="special">{</span>
  67. <span class="comment">// Wrapped object constructed in-place</span>
  68. <span class="comment">// No temporary created.</span>
  69. <span class="identifier">W</span> <span class="special">(</span><span class="number">123</span><span class="special">,</span><span class="string">"hello"</span><span class="special">)</span> <span class="special">;</span>
  70. <span class="special">}</span>
  71. </pre>
  72. <p>
  73. A limitation of this method is that it doesn't scale well to wrapped objects
  74. with multiple constructors nor to generic code were the constructor overloads
  75. are unknown.
  76. </p>
  77. <p>
  78. The solution presented in this library is the family of <span class="bold"><strong>InPlaceFactories</strong></span>
  79. and <span class="bold"><strong>TypedInPlaceFactories</strong></span>. These factories
  80. are a family of classes which encapsulate an increasing number of arbitrary
  81. constructor parameters and supply a method to construct an object of a given
  82. type using those parameters at an address specified by the user via placement
  83. new.
  84. </p>
  85. <p>
  86. For example, one member of this family looks like:
  87. </p>
  88. <pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span><span class="keyword">class</span> <span class="identifier">A0</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">A1</span><span class="special">&gt;</span>
  89. <span class="keyword">class</span> <span class="identifier">TypedInPlaceFactory2</span>
  90. <span class="special">{</span>
  91. <span class="identifier">A0</span> <span class="identifier">m_a0</span> <span class="special">;</span> <span class="identifier">A1</span> <span class="identifier">m_a1</span> <span class="special">;</span>
  92. <span class="keyword">public</span><span class="special">:</span>
  93. <span class="identifier">TypedInPlaceFactory2</span><span class="special">(</span> <span class="identifier">A0</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">a0</span><span class="special">,</span> <span class="identifier">A1</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">a1</span> <span class="special">)</span> <span class="special">:</span> <span class="identifier">m_a0</span><span class="special">(</span><span class="identifier">a0</span><span class="special">),</span> <span class="identifier">m_a1</span><span class="special">(</span><span class="identifier">a1</span><span class="special">)</span> <span class="special">{}</span>
  94. <span class="keyword">void</span> <span class="identifier">construct</span> <span class="special">(</span> <span class="keyword">void</span><span class="special">*</span> <span class="identifier">p</span> <span class="special">)</span> <span class="special">{</span> <span class="keyword">new</span> <span class="special">(</span><span class="identifier">p</span><span class="special">)</span> <span class="identifier">T</span><span class="special">(</span><span class="identifier">m_a0</span><span class="special">,</span><span class="identifier">m_a1</span><span class="special">)</span> <span class="special">;</span> <span class="special">}</span>
  95. <span class="special">}</span> <span class="special">;</span>
  96. </pre>
  97. <p>
  98. A wrapper class aware of this can use it as:
  99. </p>
  100. <pre class="programlisting"><span class="keyword">class</span> <span class="identifier">W</span>
  101. <span class="special">{</span>
  102. <span class="identifier">X</span> <span class="identifier">wrapped_</span> <span class="special">;</span>
  103. <span class="keyword">public</span><span class="special">:</span>
  104. <span class="identifier">W</span> <span class="special">(</span> <span class="identifier">X</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">x</span> <span class="special">)</span> <span class="special">:</span> <span class="identifier">wrapped_</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span> <span class="special">{}</span>
  105. <span class="identifier">W</span> <span class="special">(</span> <span class="identifier">TypedInPlaceFactory2</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">fac</span> <span class="special">)</span> <span class="special">{</span> <span class="identifier">fac</span><span class="special">.</span><span class="identifier">construct</span><span class="special">(&amp;</span><span class="identifier">wrapped_</span><span class="special">)</span> <span class="special">;</span> <span class="special">}</span>
  106. <span class="special">}</span> <span class="special">;</span>
  107. <span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
  108. <span class="special">{</span>
  109. <span class="comment">// Wrapped object constructed in-place via a TypedInPlaceFactory.</span>
  110. <span class="comment">// No temporary created.</span>
  111. <span class="identifier">W</span> <span class="special">(</span> <span class="identifier">TypedInPlaceFactory2</span><span class="special">&lt;</span><span class="identifier">X</span><span class="special">,</span><span class="keyword">int</span><span class="special">,</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;(</span><span class="number">123</span><span class="special">,</span><span class="string">"hello"</span><span class="special">))</span> <span class="special">;</span>
  112. <span class="special">}</span>
  113. </pre>
  114. <p>
  115. The factories are divided in two groups:
  116. </p>
  117. <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
  118. <li class="listitem">
  119. <span class="underline">TypedInPlaceFactories</span>: those which
  120. take the target type as a primary template parameter.
  121. </li>
  122. <li class="listitem">
  123. <span class="underline">InPlaceFactories</span>: those with a template
  124. <code class="computeroutput"><span class="identifier">construct</span><span class="special">(</span><span class="keyword">void</span><span class="special">*)</span></code> member
  125. function taking the target type.
  126. </li>
  127. </ul></div>
  128. <p>
  129. Within each group, all the family members differ only in the number of parameters
  130. allowed.
  131. </p>
  132. <p>
  133. This library provides an overloaded set of helper template functions to construct
  134. these factories without requiring unnecessary template parameters:
  135. </p>
  136. <pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">A0</span><span class="special">,...,</span><span class="keyword">class</span> <span class="identifier">AN</span><span class="special">&gt;</span>
  137. <span class="identifier">InPlaceFactoryN</span> <span class="special">&lt;</span><span class="identifier">A0</span><span class="special">,...,</span><span class="identifier">AN</span><span class="special">&gt;</span> <span class="identifier">in_place</span> <span class="special">(</span> <span class="identifier">A0</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">a0</span><span class="special">,</span> <span class="special">...,</span> <span class="identifier">AN</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">aN</span><span class="special">)</span> <span class="special">;</span>
  138. <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span><span class="keyword">class</span> <span class="identifier">A0</span><span class="special">,...,</span><span class="keyword">class</span> <span class="identifier">AN</span><span class="special">&gt;</span>
  139. <span class="identifier">TypedInPlaceFactoryN</span> <span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span><span class="identifier">A0</span><span class="special">,...,</span><span class="identifier">AN</span><span class="special">&gt;</span> <span class="identifier">in_place</span> <span class="special">(</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">a0</span><span class="special">,</span> <span class="identifier">A0</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">a0</span><span class="special">,</span> <span class="special">...,</span> <span class="identifier">AN</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">aN</span><span class="special">)</span> <span class="special">;</span>
  140. </pre>
  141. <p>
  142. In-place factories can be used generically by the wrapper and user as follows:
  143. </p>
  144. <pre class="programlisting"><span class="keyword">class</span> <span class="identifier">W</span>
  145. <span class="special">{</span>
  146. <span class="identifier">X</span> <span class="identifier">wrapped_</span> <span class="special">;</span>
  147. <span class="keyword">public</span><span class="special">:</span>
  148. <span class="identifier">W</span> <span class="special">(</span> <span class="identifier">X</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">x</span> <span class="special">)</span> <span class="special">:</span> <span class="identifier">wrapped_</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span> <span class="special">{}</span>
  149. <span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">class</span> <span class="identifier">InPlaceFactory</span> <span class="special">&gt;</span>
  150. <span class="identifier">W</span> <span class="special">(</span> <span class="identifier">InPlaceFactory</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">fac</span> <span class="special">)</span> <span class="special">{</span> <span class="identifier">fac</span><span class="special">.</span><span class="keyword">template</span> <span class="special">&lt;</span><span class="identifier">X</span><span class="special">&gt;</span><span class="identifier">construct</span><span class="special">(&amp;</span><span class="identifier">wrapped_</span><span class="special">)</span> <span class="special">;</span> <span class="special">}</span>
  151. <span class="special">}</span> <span class="special">;</span>
  152. <span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
  153. <span class="special">{</span>
  154. <span class="comment">// Wrapped object constructed in-place via a InPlaceFactory.</span>
  155. <span class="comment">// No temporary created.</span>
  156. <span class="identifier">W</span> <span class="special">(</span> <span class="identifier">in_place</span><span class="special">(</span><span class="number">123</span><span class="special">,</span><span class="string">"hello"</span><span class="special">)</span> <span class="special">)</span> <span class="special">;</span>
  157. <span class="special">}</span>
  158. </pre>
  159. <p>
  160. The factories are implemented in the headers: <a href="../../../../../boost/utility/in_place_factory.hpp" target="_top">in_place_factory.hpp</a>
  161. and <a href="../../../../../boost/utility/typed_in_place_factory.hpp" target="_top">typed_in_place_factory.hpp</a>
  162. </p>
  163. </div>
  164. <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
  165. <td align="left"></td>
  166. <td align="right"><div class="copyright-footer">Copyright &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014 Andrzej Krzemie&#324;ski<p>
  167. Distributed under the Boost Software License, Version 1.0. (See accompanying
  168. 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>)
  169. </p>
  170. </div></td>
  171. </tr></table>
  172. <hr>
  173. <div class="spirit-nav">
  174. <a accesskey="p" href="detailed_semantics.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="a_note_about_optional_bool_.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
  175. </div>
  176. </body>
  177. </html>