Imported Upstream version 1.57.0
[platform/upstream/boost.git] / doc / html / move / construct_forwarding.html
1 <html>
2 <head>
3 <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
4 <title>Constructor Forwarding</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="The Boost C++ Libraries BoostBook Documentation Subset">
8 <link rel="up" href="../move.html" title="Chapter&#160;19.&#160;Boost.Move">
9 <link rel="prev" href="move_and_containers.html" title="Containers and move semantics">
10 <link rel="next" href="move_return.html" title="Implicit Move when returning a local object">
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="move_and_containers.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../move.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="move_return.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="move.construct_forwarding"></a><a class="link" href="construct_forwarding.html" title="Constructor Forwarding">Constructor Forwarding</a>
28 </h2></div></div></div>
29 <p>
30       Consider writing a generic factory function that returns an object for a newly
31       constructed generic type. Factory functions such as this are valuable for encapsulating
32       and localizing the allocation of resources. Obviously, the factory function
33       must accept exactly the same sets of arguments as the constructors of the type
34       of objects constructed:
35     </p>
36 <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">&gt;</span> <span class="identifier">T</span><span class="special">*</span> <span class="identifier">factory_new</span><span class="special">()</span>
37 <span class="special">{</span>  <span class="keyword">return</span> <span class="keyword">new</span> <span class="identifier">T</span><span class="special">();</span>  <span class="special">}</span>
38
39 <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">T</span><span class="special">*</span> <span class="identifier">factory_new</span><span class="special">(</span><span class="identifier">a1</span><span class="special">)</span>
40 <span class="special">{</span>  <span class="keyword">return</span> <span class="keyword">new</span> <span class="identifier">T</span><span class="special">(</span><span class="identifier">a1</span><span class="special">);</span>  <span class="special">}</span>
41
42 <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">T</span><span class="special">*</span> <span class="identifier">factory_new</span><span class="special">(</span><span class="identifier">a1</span><span class="special">,</span> <span class="identifier">a2</span><span class="special">)</span>
43 <span class="special">{</span>  <span class="keyword">return</span> <span class="keyword">new</span> <span class="identifier">T</span><span class="special">(</span><span class="identifier">a1</span><span class="special">,</span> <span class="identifier">a2</span><span class="special">);</span>  <span class="special">}</span>
44 </pre>
45 <p>
46       Unfortunately, in C++03 the much bigger issue with this approach is that the
47       N-argument case would require 2^N overloads, immediately discounting this as
48       a general solution. Fortunately, most constructors take arguments by value,
49       by const-reference or by rvalue reference. If these limitations are accepted,
50       the forwarding emulation of a N-argument case requires just N overloads. This
51       library makes this emulation easy with the help of <code class="computeroutput"><span class="identifier">BOOST_FWD_REF</span></code>
52       and <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">forward</span></code>:
53     </p>
54 <p>
55 </p>
56 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">move</span><span class="special">/</span><span class="identifier">utility_core</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
57 <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
58
59 <span class="keyword">class</span> <span class="identifier">copyable_only_tester</span>
60 <span class="special">{</span>
61    <span class="keyword">public</span><span class="special">:</span>
62    <span class="identifier">copyable_only_tester</span><span class="special">()</span>
63    <span class="special">{</span>  <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"copyable_only_tester()"</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>   <span class="special">}</span>
64
65    <span class="identifier">copyable_only_tester</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">copyable_only_tester</span><span class="special">&amp;)</span>
66    <span class="special">{</span>  <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"copyable_only_tester(const copyable_only_tester&amp;)"</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>   <span class="special">}</span>
67
68    <span class="identifier">copyable_only_tester</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
69    <span class="special">{</span>  <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"copyable_only_tester(int)"</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>   <span class="special">}</span>
70
71    <span class="identifier">copyable_only_tester</span><span class="special">(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">double</span><span class="special">)</span>
72    <span class="special">{</span>  <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"copyable_only_tester(int, double)"</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>   <span class="special">}</span>
73 <span class="special">};</span>
74
75 <span class="keyword">class</span> <span class="identifier">copyable_movable_tester</span>
76 <span class="special">{</span>
77    <span class="comment">// move semantics</span>
78    <span class="identifier">BOOST_COPYABLE_AND_MOVABLE</span><span class="special">(</span><span class="identifier">copyable_movable_tester</span><span class="special">)</span>
79    <span class="keyword">public</span><span class="special">:</span>
80
81    <span class="identifier">copyable_movable_tester</span><span class="special">()</span>
82    <span class="special">{</span>  <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"copyable_movable_tester()"</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>   <span class="special">}</span>
83
84    <span class="identifier">copyable_movable_tester</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
85    <span class="special">{</span>  <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"copyable_movable_tester(int)"</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>   <span class="special">}</span>
86
87    <span class="identifier">copyable_movable_tester</span><span class="special">(</span><span class="identifier">BOOST_RV_REF</span><span class="special">(</span><span class="identifier">copyable_movable_tester</span><span class="special">))</span>
88    <span class="special">{</span>  <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"copyable_movable_tester(BOOST_RV_REF(copyable_movable_tester))"</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>   <span class="special">}</span>
89
90    <span class="identifier">copyable_movable_tester</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">copyable_movable_tester</span> <span class="special">&amp;)</span>
91    <span class="special">{</span>  <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"copyable_movable_tester(const copyable_movable_tester &amp;)"</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>   <span class="special">}</span>
92
93    <span class="identifier">copyable_movable_tester</span><span class="special">(</span><span class="identifier">BOOST_RV_REF</span><span class="special">(</span><span class="identifier">copyable_movable_tester</span><span class="special">),</span> <span class="identifier">BOOST_RV_REF</span><span class="special">(</span><span class="identifier">copyable_movable_tester</span><span class="special">))</span>
94    <span class="special">{</span>  <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"copyable_movable_tester(BOOST_RV_REF(copyable_movable_tester), BOOST_RV_REF(copyable_movable_tester))"</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>   <span class="special">}</span>
95
96    <span class="identifier">copyable_movable_tester</span> <span class="special">&amp;</span><span class="keyword">operator</span><span class="special">=(</span><span class="identifier">BOOST_RV_REF</span><span class="special">(</span><span class="identifier">copyable_movable_tester</span><span class="special">))</span>
97    <span class="special">{</span>  <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"copyable_movable_tester &amp; operator=(BOOST_RV_REF(copyable_movable_tester))"</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
98       <span class="keyword">return</span> <span class="special">*</span><span class="keyword">this</span><span class="special">;</span>  <span class="special">}</span>
99
100    <span class="identifier">copyable_movable_tester</span> <span class="special">&amp;</span><span class="keyword">operator</span><span class="special">=(</span><span class="identifier">BOOST_COPY_ASSIGN_REF</span><span class="special">(</span><span class="identifier">copyable_movable_tester</span><span class="special">))</span>
101    <span class="special">{</span>  <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"copyable_movable_tester &amp; operator=(BOOST_COPY_ASSIGN_REF(copyable_movable_tester))"</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
102       <span class="keyword">return</span> <span class="special">*</span><span class="keyword">this</span><span class="special">;</span>  <span class="special">}</span>
103 <span class="special">};</span>
104
105 <span class="comment">//1 argument</span>
106 <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">MaybeMovable</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">MaybeRv</span><span class="special">&gt;</span>
107 <span class="keyword">void</span> <span class="identifier">function_construct</span><span class="special">(</span><span class="identifier">BOOST_FWD_REF</span><span class="special">(</span><span class="identifier">MaybeRv</span><span class="special">)</span> <span class="identifier">x</span><span class="special">)</span>
108 <span class="special">{</span>  <span class="identifier">MaybeMovable</span> <span class="identifier">m</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">MaybeRv</span><span class="special">&gt;(</span><span class="identifier">x</span><span class="special">));</span>   <span class="special">}</span>
109
110 <span class="comment">//2 argument</span>
111 <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">MaybeMovable</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">MaybeRv</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">MaybeRv2</span><span class="special">&gt;</span>
112 <span class="keyword">void</span> <span class="identifier">function_construct</span><span class="special">(</span><span class="identifier">BOOST_FWD_REF</span><span class="special">(</span><span class="identifier">MaybeRv</span><span class="special">)</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">BOOST_FWD_REF</span><span class="special">(</span><span class="identifier">MaybeRv2</span><span class="special">)</span> <span class="identifier">x2</span><span class="special">)</span>
113 <span class="special">{</span>  <span class="identifier">MaybeMovable</span> <span class="identifier">m</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">MaybeRv</span><span class="special">&gt;(</span><span class="identifier">x</span><span class="special">),</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">MaybeRv2</span><span class="special">&gt;(</span><span class="identifier">x2</span><span class="special">));</span>  <span class="special">}</span>
114
115 <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
116 <span class="special">{</span>
117    <span class="identifier">copyable_movable_tester</span> <span class="identifier">m</span><span class="special">;</span>
118    <span class="comment">//move constructor</span>
119    <span class="identifier">function_construct</span><span class="special">&lt;</span><span class="identifier">copyable_movable_tester</span><span class="special">&gt;(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">m</span><span class="special">));</span>
120    <span class="comment">//copy constructor</span>
121    <span class="identifier">function_construct</span><span class="special">&lt;</span><span class="identifier">copyable_movable_tester</span><span class="special">&gt;(</span><span class="identifier">copyable_movable_tester</span><span class="special">());</span>
122    <span class="comment">//two rvalue constructor</span>
123    <span class="identifier">function_construct</span><span class="special">&lt;</span><span class="identifier">copyable_movable_tester</span><span class="special">&gt;(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">m</span><span class="special">),</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">m</span><span class="special">));</span>
124
125    <span class="identifier">copyable_only_tester</span> <span class="identifier">nm</span><span class="special">;</span>
126    <span class="comment">//copy constructor (copyable_only_tester has no move ctor.)</span>
127    <span class="identifier">function_construct</span><span class="special">&lt;</span><span class="identifier">copyable_only_tester</span><span class="special">&gt;(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">nm</span><span class="special">));</span>
128    <span class="comment">//copy constructor</span>
129    <span class="identifier">function_construct</span><span class="special">&lt;</span><span class="identifier">copyable_only_tester</span><span class="special">&gt;(</span><span class="identifier">nm</span><span class="special">);</span>
130    <span class="comment">//int constructor</span>
131    <span class="identifier">function_construct</span><span class="special">&lt;</span><span class="identifier">copyable_only_tester</span><span class="special">&gt;(</span><span class="keyword">int</span><span class="special">(</span><span class="number">0</span><span class="special">));</span>
132    <span class="comment">//int, double constructor</span>
133    <span class="identifier">function_construct</span><span class="special">&lt;</span><span class="identifier">copyable_only_tester</span><span class="special">&gt;(</span><span class="keyword">int</span><span class="special">(</span><span class="number">0</span><span class="special">),</span> <span class="keyword">double</span><span class="special">(</span><span class="number">0.0</span><span class="special">));</span>
134
135    <span class="comment">//Output is:</span>
136    <span class="comment">//copyable_movable_tester()</span>
137    <span class="comment">//copyable_movable_tester(BOOST_RV_REF(copyable_movable_tester))</span>
138    <span class="comment">//copyable_movable_tester()</span>
139    <span class="comment">//copyable_movable_tester(const copyable_movable_tester &amp;)</span>
140    <span class="comment">//copyable_movable_tester(BOOST_RV_REF(copyable_movable_tester), BOOST_RV_REF(copyable_movable_tester))</span>
141    <span class="comment">//copyable_only_tester()</span>
142    <span class="comment">//copyable_only_tester(const copyable_only_tester&amp;)</span>
143    <span class="comment">//copyable_only_tester(const copyable_only_tester&amp;)</span>
144    <span class="comment">//copyable_only_tester(int)</span>
145    <span class="comment">//copyable_only_tester(int, double)</span>
146    <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
147 <span class="special">}</span>
148 </pre>
149 <p>
150     </p>
151 <p>
152       Constructor forwarding comes in handy to implement placement insertion in containers
153       with just N overloads if the implementor accepts the limitations of this type
154       of forwarding for C++03 compilers. In compilers with rvalue references perfect
155       forwarding is achieved.
156     </p>
157 </div>
158 <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
159 <td align="left"></td>
160 <td align="right"><div class="copyright-footer">Copyright &#169; 2008-2014 Ion Gaztanaga<p>
161         Distributed under the Boost Software License, Version 1.0. (See accompanying
162         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>)
163       </p>
164 </div></td>
165 </tr></table>
166 <hr>
167 <div class="spirit-nav">
168 <a accesskey="p" href="move_and_containers.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../move.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="move_return.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
169 </div>
170 </body>
171 </html>