Imported Upstream version 1.64.0
[platform/upstream/boost.git] / doc / html / typeof / other.html
1 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
2 <html>
3 <head>
4 <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
5 <title>Other considerations and tips</title>
6 <link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
7 <meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
8 <link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
9 <link rel="up" href="../typeof.html" title="Chapter&#160;42.&#160;Boost.Typeof">
10 <link rel="prev" href="refe.html" title="Reference">
11 <link rel="next" href="cont.html" title="Contributed By:">
12 </head>
13 <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
14 <table cellpadding="2" width="100%"><tr>
15 <td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
16 <td align="center"><a href="../../../index.html">Home</a></td>
17 <td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
18 <td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
19 <td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
20 <td align="center"><a href="../../../more/index.htm">More</a></td>
21 </tr></table>
22 <hr>
23 <div class="spirit-nav">
24 <a accesskey="p" href="refe.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../typeof.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="cont.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
25 </div>
26 <div class="section">
27 <div class="titlepage"><div><div><h2 class="title" style="clear: both">
28 <a name="typeof.other"></a>Other considerations and tips</h2></div></div></div>
29 <div class="toc"><dl class="toc">
30 <dt><span class="section"><a href="other.html#typeof.natem">Native typeof support and emulation</a></span></dt>
31 <dt><span class="section"><a href="other.html#typeof.parties">The three participating parties</a></span></dt>
32 <dt><span class="section"><a href="other.html#typeof.features">Supported features</a></span></dt>
33 <dt><span class="section"><a href="other.html#typeof.what">What needs to be registered?</a></span></dt>
34 <dt><span class="section"><a href="other.html#typeof.limi">Limitations</a></span></dt>
35 </dl></div>
36 <div class="section">
37 <div class="titlepage"><div><div><h3 class="title">
38 <a name="typeof.natem"></a>Native typeof support and emulation</h3></div></div></div>
39 <p>
40         Many compilers support typeof already, most noticeable GCC and Metrowerks.
41       </p>
42 <p>
43         Igor Chesnokov discovered a method that allows to implement <code class="computeroutput"><span class="identifier">typeof</span></code> on the VC series of compilers. It
44         uses a bug in the Microsoft compiler that allows a nested class of base to
45         be defined in a class derived from base:
46       </p>
47 <pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">int</span> <span class="identifier">ID</span><span class="special">&gt;</span> <span class="keyword">struct</span> <span class="identifier">typeof_access</span>
48 <span class="special">{</span>
49     <span class="keyword">struct</span> <span class="identifier">id2type</span><span class="special">;</span> <span class="comment">//not defined</span>
50 <span class="special">};</span>
51
52 <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">int</span> <span class="identifier">ID</span><span class="special">&gt;</span> <span class="keyword">struct</span> <span class="identifier">typeof_register</span> <span class="special">:</span> <span class="identifier">typeof_access</span>
53 <span class="special">{</span>
54     <span class="comment">// define base's nested class here</span>
55     <span class="keyword">struct</span> <span class="identifier">typeof_access</span><span class="special">::</span><span class="identifier">id2type</span>
56     <span class="special">{</span>
57         <span class="keyword">typedef</span> <span class="identifier">T</span> <span class="identifier">type</span><span class="special">;</span>
58     <span class="special">};</span>
59 <span class="special">};</span>
60
61 <span class="comment">//Type registration function </span>
62 <span class="identifier">typeof_register</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">compile</span><span class="special">-</span><span class="identifier">time</span><span class="special">-</span><span class="identifier">constant</span><span class="special">&gt;</span> <span class="identifier">register_type</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;);</span>
63
64 <span class="comment">//Actually register type by instantiating typeof_register for the correct type</span>
65 <span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">register_type</span><span class="special">(</span><span class="identifier">some</span><span class="special">-</span><span class="identifier">type</span><span class="special">));</span>
66
67 <span class="comment">//Use the base class to access the type.</span>
68 <span class="keyword">typedef</span> <span class="identifier">typeof_access</span><span class="special">::</span><span class="identifier">id2type</span><span class="special">::</span><span class="identifier">type</span> <span class="identifier">type</span><span class="special">;</span>
69 </pre>
70 <p>
71         Peder Holt adapted this method to VC7.0, where the nested class is a template
72         class that is specialized in the derived class.
73       </p>
74 <p>
75         In VC8.0, it seemed that all the bug-featire had been fixed, but Steven Watanabe
76         managed to implement a more rigorous version of the VC7.0 fix that enables
77         'typeof' to be supported 'natively' here as well.
78       </p>
79 <p>
80         For many other compilers neither native <code class="computeroutput"><span class="identifier">typeof</span></code>
81         support nor the trick described above is an option. For such compilers the
82         emulation method is the only way of implementing <code class="computeroutput"><span class="identifier">typeof</span></code>.
83       </p>
84 <p>
85         According to a rough estimate, at the time of this writing the introduction
86         of the <code class="computeroutput"><span class="identifier">typeof</span></code>, <code class="computeroutput"><span class="keyword">auto</span></code>, etc., into the C++ standard may not
87         happen soon. Even after it's done, some time still has to pass before most
88         compilers implement this feature. But even after that, there always are legacy
89         compilers to support (for example now, in 2005, many people are still using
90         VC6, long after VC7.x, and even VC8.0 beta became available).
91       </p>
92 <p>
93         Considering extreme usefulness of the feature right now, it seems to make
94         sense to implement it at the library level.
95       </p>
96 <p>
97         The emulation mode seems to be important even if a better option is present
98         on some particular compiler. If a library author wants to develop portable
99         code using <code class="computeroutput"><span class="identifier">typeof</span></code>, she needs
100         to use emulation mode and register her types and templates. Those users who
101         have a better option can still take advantage of it, since the registration
102         macros are defined as no-op on such compilers, while the users for whom emulation
103         is the only option will use it.
104       </p>
105 <p>
106         The other consideration applies to the users of VC7.1. Even though the more
107         convenient <code class="computeroutput"><span class="identifier">typeof</span></code> trick is
108         available, the possibility of upgrade to VC8, where emulation remains the
109         only option, should be considered.
110       </p>
111 <p>
112         The emulation mode can be forced on the compilers that don't use it by default
113         by defining the <code class="computeroutput"><span class="identifier">BOOST_TYPEOF_COMPLIANT</span></code>
114         symbol:
115       </p>
116 <pre class="programlisting"><span class="identifier">g</span><span class="special">++</span> <span class="special">-</span><span class="identifier">D</span> <span class="identifier">BOOST_TYPEOF_COMPLIANT</span> <span class="special">-</span><span class="identifier">I</span> <span class="special">\</span><span class="identifier">boost</span><span class="special">\</span><span class="identifier">boost_1_32_0</span> <span class="identifier">main</span><span class="special">.</span><span class="identifier">cpp</span>
117 </pre>
118 </div>
119 <div class="section">
120 <div class="titlepage"><div><div><h3 class="title">
121 <a name="typeof.parties"></a>The three participating parties</h3></div></div></div>
122 <p>
123         The Lambda example from the Motivation section requires the following registration:
124       </p>
125 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="identifier">BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP</span><span class="special">()</span>
126
127 <span class="identifier">BOOST_TYPEOF_REGISTER_TEMPLATE</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">tuples</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">,</span> <span class="number">2</span><span class="special">);</span>
128 <span class="identifier">BOOST_TYPEOF_REGISTER_TEMPLATE</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">lambda</span><span class="special">::</span><span class="identifier">lambda_functor</span><span class="special">,</span> <span class="number">1</span><span class="special">);</span>
129 <span class="identifier">BOOST_TYPEOF_REGISTER_TEMPLATE</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">lambda</span><span class="special">::</span><span class="identifier">lambda_functor_base</span><span class="special">,</span> <span class="number">2</span><span class="special">);</span>
130 <span class="identifier">BOOST_TYPEOF_REGISTER_TEMPLATE</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">lambda</span><span class="special">::</span><span class="identifier">relational_action</span><span class="special">,</span> <span class="number">1</span><span class="special">);</span>
131 <span class="identifier">BOOST_TYPEOF_REGISTER_TEMPLATE</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">lambda</span><span class="special">::</span><span class="identifier">logical_action</span><span class="special">,</span> <span class="number">1</span><span class="special">);</span>
132 <span class="identifier">BOOST_TYPEOF_REGISTER_TEMPLATE</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">lambda</span><span class="special">::</span><span class="identifier">other_action</span><span class="special">,</span> <span class="number">1</span><span class="special">);</span>
133 <span class="identifier">BOOST_TYPEOF_REGISTER_TYPE</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">lambda</span><span class="special">::</span><span class="identifier">greater_action</span><span class="special">);</span>
134 <span class="identifier">BOOST_TYPEOF_REGISTER_TYPE</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">lambda</span><span class="special">::</span><span class="identifier">less_action</span><span class="special">);</span>
135 <span class="identifier">BOOST_TYPEOF_REGISTER_TYPE</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">lambda</span><span class="special">::</span><span class="identifier">and_action</span><span class="special">);</span>
136 <span class="identifier">BOOST_TYPEOF_REGISTER_TEMPLATE</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">lambda</span><span class="special">::</span><span class="identifier">placeholder</span><span class="special">,</span> <span class="special">(</span><span class="keyword">int</span><span class="special">));</span>
137 </pre>
138 <p>
139         It may seem that the price for the ability to discover the expression's type
140         is too high: rather large amount of registration is required. However note
141         that all of the above registration is done only once, and after that, any
142         combination of the registered types and templates would be handled. Moreover,
143         this registration is typically done not by the end-user, but rather by a
144         layer on top of some library (in this example -- Boost.Lambda).
145       </p>
146 <p>
147         When thinking about this, it's helpful to consider three parties: the typeof
148         facility, the library (probably built on expression templates principle),
149         and the end-user. The typeof facility is responsible for registering fundamental
150         types. The library can register its own types and templates.
151       </p>
152 <p>
153         In the best-case scenario, if the expressions always consist of only fundamental
154         types and library-defined types and templates, a library author can achieve
155         the impression that the <code class="computeroutput"><span class="identifier">typeof</span></code>
156         is natively supported for her library. On the other hand, the more often
157         expressions contain user-defined types, the more responsibility is put on
158         the end-user, and therefore the less attractive this approach becomes.
159       </p>
160 <p>
161         Thus, the ratio of user-defined types in the expressions should be the main
162         factor to consider when deciding whether or not to apply the typeof facility.
163       </p>
164 </div>
165 <div class="section">
166 <div class="titlepage"><div><div><h3 class="title">
167 <a name="typeof.features"></a>Supported features</h3></div></div></div>
168 <p>
169         The Typeof library pre-registers fundamental types. For these types, and
170         for any other types/templates registered by the user library or end-user,
171         any combination of the following is supported:
172       </p>
173 <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
174 <li class="listitem">
175             Pointers;
176           </li>
177 <li class="listitem">
178             References (except top-level);
179           </li>
180 <li class="listitem">
181             Consts (except top-level);
182           </li>
183 <li class="listitem">
184             Volatiles (except top-level);
185           </li>
186 <li class="listitem">
187             Arrays;
188           </li>
189 <li class="listitem">
190             Functions, function pointers, and references;
191           </li>
192 <li class="listitem">
193             Pointers to member functions;
194           </li>
195 <li class="listitem">
196             Pointers to data members.
197           </li>
198 </ul></div>
199 <p>
200         For example the following type:
201       </p>
202 <pre class="programlisting"><span class="keyword">int</span><span class="special">&amp;</span> <span class="special">(*)(</span><span class="keyword">const</span> <span class="keyword">volatile</span> <span class="keyword">char</span><span class="special">*,</span> <span class="keyword">double</span><span class="special">[</span><span class="number">5</span><span class="special">],</span> <span class="keyword">void</span><span class="special">(*)(</span><span class="keyword">short</span><span class="special">))</span>
203 </pre>
204 <p>
205         is supported right away, and something like:
206       </p>
207 <pre class="programlisting"><span class="keyword">void</span> <span class="special">(</span><span class="identifier">MyClass</span><span class="special">::*)(</span><span class="keyword">int</span> <span class="identifier">MyClass</span><span class="special">::*,</span> <span class="identifier">MyClass</span><span class="special">[</span><span class="number">10</span><span class="special">])</span> <span class="keyword">const</span>
208 </pre>
209 <p>
210         is supported provided <code class="computeroutput"><span class="identifier">MyClass</span></code>
211         is registered.
212       </p>
213 <p>
214         The Typeof Library also provides registration files for most STL classes/templates.
215         These files are located in the std subdirectory, and named after corresponding
216         STL headers. These files are not included by the typeof system and have to
217         be explicitly included by the user, as needed:
218       </p>
219 <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">typeof</span><span class="special">/</span><span class="identifier">std</span><span class="special">/</span><span class="identifier">functional</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
220 <span class="identifier">BOOST_AUTO</span><span class="special">(</span><span class="identifier">fun</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">bind2nd</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">less</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(),</span> <span class="number">21</span><span class="special">));</span> <span class="comment">//create named function object for future use.</span>
221 </pre>
222 </div>
223 <div class="section">
224 <div class="titlepage"><div><div><h3 class="title">
225 <a name="typeof.what"></a>What needs to be registered?</h3></div></div></div>
226 <p>
227         It is possible to take advantage of the compiler when registering types for
228         the Typeof Library. Even though there is currently no direct support for
229         typeof in the language, the compiler is aware of what the type of an expression
230         is, and gives an error if it encounters an expression that has not been handled
231         correctly. In the <code class="computeroutput"><span class="identifier">typeof</span></code>
232         context, this error message will contain clues to what types needs to be
233         registered with the Typeof Library in order for <code class="computeroutput"><span class="identifier">BOOST_TYPEOF</span></code>
234         to work.
235       </p>
236 <pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">X</span> <span class="special">{};</span>
237
238 <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">A</span><span class="special">,</span><span class="keyword">bool</span> <span class="identifier">B</span><span class="special">&gt;</span>
239 <span class="keyword">struct</span> <span class="identifier">Y</span> <span class="special">{};</span>
240
241 <span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span><span class="identifier">X</span><span class="special">,</span><span class="identifier">Y</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span><span class="keyword">true</span><span class="special">&gt;</span> <span class="special">&gt;</span> <span class="identifier">a</span><span class="special">;</span>
242
243 <span class="identifier">BOOST_AUTO</span><span class="special">(</span><span class="identifier">a</span><span class="special">,</span><span class="identifier">b</span><span class="special">);</span>
244 </pre>
245 <p>
246         We get the following error message from VC7.1
247       </p>
248 <pre class="programlisting">error C2504: 'boost::type_of::'anonymous-namespace'::encode_type_impl&lt;V,Type_Not_Registered_With_Typeof_System&gt;' : base
249     class undefined
250         with
251         [
252             V=boost::type_of::'anonymous-namespace'::encode_type_impl&lt;boost::mpl::vector0&lt;boost::mpl::na&gt;,std::pair&lt;X,Y&lt;int,true&gt;&gt;&gt;::V0,
253             Type_Not_Registered_With_Typeof_System=X
254         ]
255 </pre>
256 <p>
257         Inspecting this error message, we see that the compiler complains about
258         <code class="computeroutput"><span class="identifier">X</span></code>
259       </p>
260 <pre class="programlisting"><span class="identifier">BOOST_TYPEOF_REGISTER_TYPE</span><span class="special">(</span><span class="identifier">X</span><span class="special">);</span> <span class="comment">//register X with the typeof system</span>
261 </pre>
262 <p>
263         Recompiling, we get a new error message from VC7.1
264       </p>
265 <pre class="programlisting">error C2504: 'boost::type_of::'anonymous-namespace'::encode_type_impl&lt;V,Type_Not_Registered_With_Typeof_System&gt;' : base
266     class undefined
267         with
268         [
269             V=boost::type_of::'anonymous-namespace'::encode_type_impl&lt;boost::mpl::vector0&lt;boost::mpl::na&gt;,std::pair&lt;X,Y&lt;int,true&gt;&gt;&gt;::V1,
270             Type_Not_Registered_With_Typeof_System=Y&lt;int,true&gt;
271         ]
272 </pre>
273 <p>
274         Inspecting this error message, we see that the compiler complains about
275         <code class="computeroutput"><span class="identifier">Y</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span><span class="keyword">true</span><span class="special">&gt;</span></code>. Since <code class="computeroutput"><span class="identifier">Y</span></code>
276         is a template, and contains integral constants, we need to take more care
277         when registering:
278       </p>
279 <pre class="programlisting"><span class="identifier">BOOST_TYPEOF_REGISTER_TEMPLATE</span><span class="special">(</span><span class="identifier">Y</span><span class="special">,(</span><span class="keyword">typename</span><span class="special">)(</span><span class="keyword">bool</span><span class="special">));</span> <span class="comment">//register template class Y</span>
280 </pre>
281 <p>
282         It is a good idea to look up the exact definition of <code class="computeroutput"><span class="identifier">Y</span></code>
283         when it contains integral constants. For simple template classes containing
284         only typenames, you can rely solely on the compiler error.
285       </p>
286 <p>
287         The above code now compiles.
288       </p>
289 <p>
290         This technique can be used to get an overview of which types needs to be
291         registered for a given project in order to support <code class="computeroutput"><span class="identifier">typeof</span></code>.
292       </p>
293 </div>
294 <div class="section">
295 <div class="titlepage"><div><div><h3 class="title">
296 <a name="typeof.limi"></a>Limitations</h3></div></div></div>
297 <p>
298         Nested template template parameters are not supported, like:
299       </p>
300 <pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span><span class="special">&gt;</span> <span class="keyword">class</span><span class="special">&gt;</span> <span class="keyword">class</span> <span class="identifier">Tpl</span><span class="special">&gt;</span>
301 <span class="keyword">class</span> <span class="identifier">A</span><span class="special">;</span> <span class="comment">// can't register!</span>
302 </pre>
303 <p>
304         Classes and templates nested inside other templates also can't be registered
305         because of the issue of nondeduced context. This limitation is most noticeable
306         with regards to standard iterators in Dinkumware STL, which are implemented
307         as nested classes. Instead, instantiations can be registered:
308       </p>
309 <pre class="programlisting"><span class="identifier">BOOST_TYPEOF_REGISTER_TYPE</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;::</span><span class="identifier">const_iterator</span><span class="special">)</span>
310 </pre>
311 </div>
312 </div>
313 <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
314 <td align="left"></td>
315 <td align="right"><div class="copyright-footer">Copyright &#169; 2004, 2005 Arkadiy Vertleyb, Peder Holt<p>
316         Distributed under the Boost Software License, Version 1.0. (See accompanying
317         file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">
318         http://www.boost.org/LICENSE_1_0.txt </a>)
319       </p>
320 </div></td>
321 </tr></table>
322 <hr>
323 <div class="spirit-nav">
324 <a accesskey="p" href="refe.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../typeof.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="cont.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
325 </div>
326 </body>
327 </html>