tti_nested_type.html 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549
  1. <html>
  2. <head>
  3. <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
  4. <title>Nested Types</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;The Type Traits Introspection Library">
  8. <link rel="up" href="../index.html" title="Chapter&#160;1.&#160;The Type Traits Introspection Library">
  9. <link rel="prev" href="tti_detail_has_function.html" title="Introspecting an inner function">
  10. <link rel="next" href="tti_func_sig.html" title="Nested Types and Function Signatures">
  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="tti_detail_has_function.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="tti_func_sig.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="the_type_traits_introspection_library.tti_nested_type"></a><a class="link" href="tti_nested_type.html" title="Nested Types">Nested
  28. Types</a>
  29. </h2></div></div></div>
  30. <p>
  31. Besides the functionality of the TTI library which queries whether some inner
  32. element of a given name within a type exists, the library also includes functionality
  33. for generating a nested type if it exists, else a marker type if it does not
  34. exist. By marker type is meant a type either internally created by the library,
  35. with no functionality, or designated by the end-user to represent the same
  36. idea.
  37. </p>
  38. <p>
  39. First I will explain the syntax and use of this functionality and then the
  40. reason it exists in the library.
  41. </p>
  42. <p>
  43. The functionality is a metafunction created by the macro <code class="computeroutput"><a class="link" href="../BOOST_TTI_MEMBER_TYPE.html" title="Macro BOOST_TTI_MEMBER_TYPE">BOOST_TTI_MEMBER_TYPE</a></code>.
  44. The macro takes a single parameter, which is the name of a nested type. We
  45. will call this our 'named type'. The macro generates a metafunction called
  46. <code class="computeroutput"><span class="identifier">member_type_</span><span class="char">'named_type'</span></code>
  47. which, passed an enclosing type, returns the named type if it exists, else
  48. a marker type if it does not.
  49. </p>
  50. <p>
  51. As with our other macros we can use the alternative form of the macro <code class="computeroutput"><a class="link" href="../BOOST_TT_idm46187185643920.html" title="Macro BOOST_TTI_TRAIT_MEMBER_TYPE">BOOST_TTI_TRAIT_MEMBER_TYPE</a></code> to
  52. pass first the name of the metafunction to be generated and then the name of
  53. the 'named type'. After that the functionality of our resulting metafunction
  54. is exactly the same.
  55. </p>
  56. <p>
  57. Its general explanation is given as:
  58. </p>
  59. <div class="table">
  60. <a name="the_type_traits_introspection_library.tti_nested_type.tbmacronested"></a><p class="title"><b>Table&#160;1.3.&#160;TTI Nested Type Macro Metafunction</b></p>
  61. <div class="table-contents"><table class="table" summary="TTI Nested Type Macro Metafunction">
  62. <colgroup>
  63. <col>
  64. <col>
  65. <col>
  66. <col>
  67. </colgroup>
  68. <thead><tr>
  69. <th>
  70. <p>
  71. Inner Element
  72. </p>
  73. </th>
  74. <th>
  75. <p>
  76. Macro
  77. </p>
  78. </th>
  79. <th>
  80. <p>
  81. Template
  82. </p>
  83. </th>
  84. <th>
  85. <p>
  86. Specific Header File
  87. </p>
  88. </th>
  89. </tr></thead>
  90. <tbody><tr>
  91. <td>
  92. <p>
  93. Type
  94. </p>
  95. </td>
  96. <td>
  97. <p>
  98. <code class="computeroutput"><a class="link" href="../BOOST_TTI_MEMBER_TYPE.html" title="Macro BOOST_TTI_MEMBER_TYPE">BOOST_TTI_MEMBER_TYPE</a></code>(name)
  99. </p>
  100. </td>
  101. <td>
  102. <p>
  103. <code class="computeroutput"><span class="identifier">member_type_</span><span class="char">'name'</span></code>
  104. </p>
  105. <p>
  106. class T = enclosing type
  107. </p>
  108. <p>
  109. class U = (optional) marker type
  110. </p>
  111. <p>
  112. returns = the type of 'name' if it exists, else a marker type, as
  113. the typedef 'type'.
  114. </p>
  115. <p>
  116. The invoked metafunction also holds the marker type as the typedef
  117. 'boost_tti_marker_type'. This is done for convenience so that the
  118. marker type does not have to be remembered.
  119. </p>
  120. </td>
  121. <td>
  122. <p>
  123. <code class="computeroutput"><a class="link" href="../header/boost/tti/member_type_hpp.html" title="Header &lt;boost/tti/member_type.hpp&gt;">member_type.hpp</a></code>
  124. </p>
  125. </td>
  126. </tr></tbody>
  127. </table></div>
  128. </div>
  129. <br class="table-break"><p>
  130. The marker type is purely optional. If not specified a type internal to the
  131. TTI library, which has no functionality, is used. Unless there is a specific
  132. reason for the end-user to provide his own marker type, he should let the TTI
  133. library use its own internal marker type.
  134. </p>
  135. <p>
  136. A simple example of this functionality would be:
  137. </p>
  138. <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">tti</span><span class="special">/</span><span class="identifier">member_type</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  139. <span class="identifier">BOOST_TTI_MEMBER_TYPE</span><span class="special">(</span><span class="identifier">ANamedType</span><span class="special">)</span>
  140. <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">member_type_ANamedType</span><span class="special">&lt;</span><span class="identifier">EnclosingType</span><span class="special">&gt;::</span><span class="identifier">type</span> <span class="identifier">AType</span><span class="special">;</span>
  141. </pre>
  142. <p>
  143. If type 'ANamedType' is a nested type of 'EnclosingType' then AType is the
  144. same type as 'ANamedType', otherwise AType is a marker type internal to the
  145. TTI library.
  146. </p>
  147. <p>
  148. Now that we have explained the syntax of BOOST_TTI_MEMBER_TYPE we can now answer
  149. the question of why this functionality to create a 'type' exists when looking
  150. for a nested type of an enclosing type.
  151. </p>
  152. <h4>
  153. <a name="the_type_traits_introspection_library.tti_nested_type.h0"></a>
  154. <span class="phrase"><a name="the_type_traits_introspection_library.tti_nested_type.the_problem"></a></span><a class="link" href="tti_nested_type.html#the_type_traits_introspection_library.tti_nested_type.the_problem">The
  155. problem</a>
  156. </h4>
  157. <p>
  158. The metafunctions generated by the TTI macros all work with various types,
  159. whether in specifying an enclosing type or in specifying the type of some inner
  160. element, which may also involve types in the signature of that element, such
  161. as a parameter or return type of a function. The C++ notation for a nested
  162. type, given an enclosing type 'T' and an inner type 'InnerType', is 'T::InnerType'.
  163. If either the enclosing type 'T' does not exist, or the inner type 'InnerType'
  164. does not exist within 'T', the expression 'T::InnerType' will give a compiler
  165. error if we attempt to use it in our template instantiation of one of TTI's
  166. macro metafunctions.
  167. </p>
  168. <p>
  169. This is a problem if we want to be able to introspect for the existence of
  170. inner elements to an enclosing type without producing compiler errors. Of course
  171. if we absolutely know what types we have and that a nested type exists, and
  172. these declarations are within our scope, we can always use an expression like
  173. 'T::InnerType' without compiler error. But this is often not the case when
  174. doing template programming since the type being passed to us at compile-time
  175. in a class or function template is chosen at instantiation time and is created
  176. by the user of a template.
  177. </p>
  178. <p>
  179. One solution to this is afforded by the library itself. Given an enclosing
  180. type 'T' which we know must exist, either because it is a top-level type we
  181. know about or it is passed to us in some template as a 'class T' or 'typename
  182. T', and given an inner type named 'InnerType' whose existence we would like
  183. ascertain, we can use a <code class="computeroutput"><span class="identifier">BOOST_TTI_HAS_TYPE</span><span class="special">(</span><span class="identifier">InnerType</span><span class="special">)</span></code> macro and it's related <code class="computeroutput"><span class="identifier">has_type_InnerType</span></code>
  184. metafunction to determine if the nested type 'InnerType' exists. This solution
  185. is perfectly valid, and in conjunction with Boost MPL's selection metafunctions,
  186. we can do compile-time selection to generate the correct template code.
  187. </p>
  188. <p>
  189. However this does not scale that well syntactically if we need to drill down
  190. further from a top-level enclosing type to a deeply nested type, or even to
  191. look for some deeply nested type's inner elements. We are going to be generating
  192. a great deal of <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">mpl</span><span class="special">::</span><span class="identifier">if_</span></code>
  193. and/or <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">mpl</span><span class="special">::</span><span class="identifier">eval_if</span></code>
  194. type selection statements to get to some final condition where we know we can
  195. generate the compile-time code which we want.
  196. </p>
  197. <h4>
  198. <a name="the_type_traits_introspection_library.tti_nested_type.h1"></a>
  199. <span class="phrase"><a name="the_type_traits_introspection_library.tti_nested_type.the_solution"></a></span><a class="link" href="tti_nested_type.html#the_type_traits_introspection_library.tti_nested_type.the_solution">The
  200. solution</a>
  201. </h4>
  202. <p>
  203. The solution given by BOOST_TTI_MEMBER_TYPE is that we can create a type as
  204. the return from our metafunction, which is the same type as a nested type if
  205. it exists or some other marker type if it does not, and then work with that
  206. returned type without producing a compiler error. If we had to use the 'T::InnerType'
  207. syntax to specify our type, where 'T' represents out enclosing type and 'InnerType'
  208. our nested type, and there was no nested type 'InnerType' within the enclosing
  209. type 'T, the compiler would give us an error immediately.
  210. </p>
  211. <p>
  212. By using BOOST_TTI_MEMBER_TYPE we have a type to work with even when such a
  213. type really does not exist. Naturally if the type does not exist, the type
  214. which we have to work with, being a marker type, will generally not fulfill
  215. any other further functionality we want from it. This is good and will normally
  216. produce the correct results in further uses of the type when doing metafunction
  217. programming. Occasionally the TTI produced marker type, when our nested type
  218. does not exist, is not sufficient for further metafunction programming. In
  219. that rare case the end-user can produce his own marker type to be used if the
  220. nested type does not exist. In any case, whether the nested type exists, whether
  221. the TTI default supplied marker type is used, or whether an end-user marker
  222. type is used, template metaprogramming can continue without a compilation problem.
  223. Furthermore this scales better than having to constant check for nested type
  224. existence via BOOST_TTI_HAS_TYPE in complicated template metaprogramming code.
  225. </p>
  226. <h4>
  227. <a name="the_type_traits_introspection_library.tti_nested_type.h2"></a>
  228. <span class="phrase"><a name="the_type_traits_introspection_library.tti_nested_type.checking_if_the_member_type_exists"></a></span><a class="link" href="tti_nested_type.html#the_type_traits_introspection_library.tti_nested_type.checking_if_the_member_type_exists">Checking
  229. if the member type exists</a>
  230. </h4>
  231. <p>
  232. Once we use BOOST_TTI_MEMBER_TYPE to generate a nested type if it exists we
  233. will normally use that type in further metafunction programming. Occasionally,
  234. given the type we generate, we will want to ask if the type is really our nested
  235. type or the marker type instead. Essentially we are asking if the type generated
  236. is the marker type or not. If it is the marker type, then the type generated
  237. is not the nested type we had hoped for. If it is not the marker type, then
  238. the type generated is the nested type we had hoped for. This is easy enough
  239. to do for the template metaprogrammer but TTI makes it easier by providing
  240. either of two metafunctions to do this calculation. These two metafunctions
  241. are 'boost::tti::valid_member_type' and 'boost::tti::valid_member_metafunction':
  242. </p>
  243. <div class="table">
  244. <a name="the_type_traits_introspection_library.tti_nested_type.existtbmacronested"></a><p class="title"><b>Table&#160;1.4.&#160;TTI Nested Type Macro Metafunction Existence</b></p>
  245. <div class="table-contents"><table class="table" summary="TTI Nested Type Macro Metafunction Existence">
  246. <colgroup>
  247. <col>
  248. <col>
  249. <col>
  250. <col>
  251. </colgroup>
  252. <thead><tr>
  253. <th>
  254. <p>
  255. Inner Element
  256. </p>
  257. </th>
  258. <th>
  259. <p>
  260. Macro
  261. </p>
  262. </th>
  263. <th>
  264. <p>
  265. Template
  266. </p>
  267. </th>
  268. <th>
  269. <p>
  270. Specific Header File
  271. </p>
  272. </th>
  273. </tr></thead>
  274. <tbody>
  275. <tr>
  276. <td>
  277. <p>
  278. Type
  279. </p>
  280. </td>
  281. <td>
  282. <p>
  283. None
  284. </p>
  285. </td>
  286. <td>
  287. <p>
  288. <code class="computeroutput"><a class="link" href="../boost/tti/valid_member_type.html" title="Struct template valid_member_type">boost::tti::valid_member_type</a></code>
  289. </p>
  290. <p>
  291. class T = a type
  292. </p>
  293. <p>
  294. class U = (optional) marker type
  295. </p>
  296. <p>
  297. returns = true if the type exists, false if it does not. 'Existence'
  298. is determined by whether the type does not equal the marker type
  299. of BOOST_TTI_MEMBER_TYPE.
  300. </p>
  301. </td>
  302. <td>
  303. <p>
  304. <code class="computeroutput"><a class="link" href="../header/boost/tti/member_type_hpp.html" title="Header &lt;boost/tti/member_type.hpp&gt;">member_type.hpp</a></code>
  305. </p>
  306. </td>
  307. </tr>
  308. <tr>
  309. <td>
  310. <p>
  311. Type
  312. </p>
  313. </td>
  314. <td>
  315. <p>
  316. None
  317. </p>
  318. </td>
  319. <td>
  320. <p>
  321. <code class="computeroutput"><a class="link" href="../boost/tti/valid_member_metafunction.html" title="Struct template valid_member_metafunction">boost::tti::valid_member_metafunction</a></code>
  322. </p>
  323. <p>
  324. class T = a metafunction type
  325. </p>
  326. <p>
  327. returns = true if the return 'type' of the metafunction exists, false
  328. if it does not.'Existence' is determined by whether the return 'type'
  329. does not equal the marker type of BOOST_TTI_MEMBER_TYPE.
  330. </p>
  331. </td>
  332. <td>
  333. <p>
  334. <code class="computeroutput"><a class="link" href="../header/boost/tti/member_type_hpp.html" title="Header &lt;boost/tti/member_type.hpp&gt;">member_type.hpp</a></code>
  335. </p>
  336. </td>
  337. </tr>
  338. </tbody>
  339. </table></div>
  340. </div>
  341. <br class="table-break"><p>
  342. In our first metafunction, 'boost::tti::valid_member_type', the first parameter
  343. is the return 'type' from invoking the metafunction generated by BOOST_TTI_MEMBER_TYPE.
  344. If when the metafunction was invoked a user-defined marker type had been specified,
  345. then the second optional parameter is that marker type, else it is not necessary
  346. to specify the optional second template parameter. Since the marker type is
  347. saved as the nested type boost::tti::marker_type once we invoke the metafunction
  348. generated by BOOST_TTI_MEMBER_TYPE we can always use that as our second template
  349. parameter to 'boost::tti::valid_member_type' if we like.
  350. </p>
  351. <p>
  352. The second metafunction, boost::tti::valid_member_metafunction, makes the process
  353. of passing our nested 'type' and our marker type a bit easier. Here the single
  354. template parameter is the invoked metafunction generated by BOOST_TTI_MEMBER_TYPE
  355. itself. It then picks out from the invoked metafunction both the return 'type'
  356. and the nested boost::tti::marker_type to do the correct calculation.
  357. </p>
  358. <p>
  359. A simple example of this functionality would be:
  360. </p>
  361. <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">tti</span><span class="special">/</span><span class="identifier">member_type</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  362. <span class="keyword">struct</span> <span class="identifier">UDMarkerType</span> <span class="special">{</span> <span class="special">};</span>
  363. <span class="identifier">BOOST_TTI_MEMBER_TYPE</span><span class="special">(</span><span class="identifier">ANamedType</span><span class="special">)</span>
  364. <span class="keyword">typedef</span> <span class="identifier">member_type_ANamedType</span><span class="special">&lt;</span><span class="identifier">EnclosingType</span><span class="special">&gt;</span> <span class="identifier">IMType</span><span class="special">;</span>
  365. <span class="keyword">typedef</span> <span class="identifier">member_type_ANamedType</span><span class="special">&lt;</span><span class="identifier">EnclosingType</span><span class="special">,</span><span class="identifier">UDMarkerType</span><span class="special">&gt;</span> <span class="identifier">IMTypeWithMarkerType</span><span class="special">;</span>
  366. </pre>
  367. <p>
  368. then
  369. </p>
  370. <pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">tti</span><span class="special">::</span><span class="identifier">valid_member_type</span><span class="special">&lt;</span><span class="identifier">IMType</span><span class="special">::</span><span class="identifier">type</span><span class="special">&gt;::</span><span class="identifier">value</span>
  371. <span class="identifier">boost</span><span class="special">::</span><span class="identifier">tti</span><span class="special">::</span><span class="identifier">valid_member_type</span><span class="special">&lt;</span><span class="identifier">IMTypeWithMarkerType</span><span class="special">::</span><span class="identifier">type</span><span class="special">,</span><span class="identifier">IMTypeWithMarkerType</span><span class="special">::</span><span class="identifier">boost_tti_marker_type</span><span class="special">&gt;::</span><span class="identifier">value</span>
  372. </pre>
  373. <p>
  374. or
  375. </p>
  376. <pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">tti</span><span class="special">::</span><span class="identifier">valid_member_metafunction</span><span class="special">&lt;</span><span class="identifier">IMType</span><span class="special">&gt;::</span><span class="identifier">value</span>
  377. <span class="identifier">boost</span><span class="special">::</span><span class="identifier">tti</span><span class="special">::</span><span class="identifier">valid_member_metafunction</span><span class="special">&lt;</span><span class="identifier">IMTypeWithMarkerType</span><span class="special">&gt;::</span><span class="identifier">value</span>
  378. </pre>
  379. <p>
  380. gives us our compile-time result.
  381. </p>
  382. <h4>
  383. <a name="the_type_traits_introspection_library.tti_nested_type.h3"></a>
  384. <span class="phrase"><a name="the_type_traits_introspection_library.tti_nested_type.an_extended_nested_type_example"></a></span><a class="link" href="tti_nested_type.html#the_type_traits_introspection_library.tti_nested_type.an_extended_nested_type_example">An
  385. extended nested type example</a>
  386. </h4>
  387. <p>
  388. As an extended example, given a type T, let us create a metafunction where
  389. there is a nested type FindType whose enclosing type is eventually T, as represented
  390. by the following structure:
  391. </p>
  392. <pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">T</span>
  393. <span class="special">{</span>
  394. <span class="keyword">struct</span> <span class="identifier">AType</span>
  395. <span class="special">{</span>
  396. <span class="keyword">struct</span> <span class="identifier">BType</span>
  397. <span class="special">{</span>
  398. <span class="keyword">struct</span> <span class="identifier">CType</span>
  399. <span class="special">{</span>
  400. <span class="keyword">struct</span> <span class="identifier">FindType</span>
  401. <span class="special">{</span>
  402. <span class="special">};</span>
  403. <span class="special">}</span>
  404. <span class="special">};</span>
  405. <span class="special">};</span>
  406. <span class="special">};</span>
  407. </pre>
  408. <p>
  409. In our TTI code we first create a series of member type macros for each of
  410. our nested types:
  411. </p>
  412. <pre class="programlisting"><span class="identifier">BOOST_TTI_MEMBER_TYPE</span><span class="special">(</span><span class="identifier">AType</span><span class="special">)</span>
  413. <span class="identifier">BOOST_TTI_MEMBER_TYPE</span><span class="special">(</span><span class="identifier">BType</span><span class="special">)</span>
  414. <span class="identifier">BOOST_TTI_MEMBER_TYPE</span><span class="special">(</span><span class="identifier">CType</span><span class="special">)</span>
  415. <span class="identifier">BOOST_TTI_MEMBER_TYPE</span><span class="special">(</span><span class="identifier">FindType</span><span class="special">)</span>
  416. </pre>
  417. <p>
  418. Next we can create a typedef to reflect a nested type called FindType which
  419. has the relationship as specified above by instantiating our macro metafunctions.
  420. We have to do this in the reverse order of our hypothetical 'struct T' above
  421. since the metafunction <code class="computeroutput"><span class="identifier">BOOST_TTI_MEMBER_TYPE</span></code>
  422. takes its enclosing type as its template parameter.
  423. </p>
  424. <pre class="programlisting"><span class="keyword">typedef</span> <span class="keyword">typename</span>
  425. <span class="identifier">member_type_FindType</span>
  426. <span class="special">&lt;</span>
  427. <span class="keyword">typename</span> <span class="identifier">member_type_CType</span>
  428. <span class="special">&lt;</span>
  429. <span class="keyword">typename</span> <span class="identifier">member_type_BType</span>
  430. <span class="special">&lt;</span>
  431. <span class="keyword">typename</span> <span class="identifier">member_type_AType</span>
  432. <span class="special">&lt;</span>
  433. <span class="identifier">T</span>
  434. <span class="special">&gt;::</span><span class="identifier">type</span>
  435. <span class="special">&gt;::</span><span class="identifier">type</span>
  436. <span class="special">&gt;::</span><span class="identifier">type</span>
  437. <span class="special">&gt;::</span><span class="identifier">type</span> <span class="identifier">MyFindType</span><span class="special">;</span>
  438. </pre>
  439. <p>
  440. We can use the above typedef to pass the type as FindType to one of our macro
  441. metafunctions. FindType may not actually exist but we will not generate a compiler
  442. error when we use it. It will only generate, if it does not exist, an eventual
  443. failure by having whatever metafunction uses such a type return a false value
  444. at compile-time.
  445. </p>
  446. <p>
  447. As one example, let's ask whether FindType has a static member data called
  448. MyData of type 'int'. We add:
  449. </p>
  450. <pre class="programlisting"><span class="identifier">BOOST_TTI_HAS_STATIC_MEMBER_DATA</span><span class="special">(</span><span class="identifier">MyData</span><span class="special">)</span>
  451. </pre>
  452. <p>
  453. Next we create our metafunction:
  454. </p>
  455. <pre class="programlisting"><span class="identifier">has_static_member_data_MyData</span>
  456. <span class="special">&lt;</span>
  457. <span class="identifier">MyFindType</span><span class="special">,</span>
  458. <span class="keyword">int</span>
  459. <span class="special">&gt;</span>
  460. </pre>
  461. <p>
  462. and use this in our metaprogramming code. Our metafunction now tells us whether
  463. the nested type FindType has a static member data called MyData of type 'int',
  464. even if FindType does not actually exist as we have specified it as a type.
  465. If we had tried to do this using normal C++ nested type notation our metafunction
  466. code above would be:
  467. </p>
  468. <pre class="programlisting"><span class="identifier">has_static_member_data_MyData</span>
  469. <span class="special">&lt;</span>
  470. <span class="keyword">typename</span> <span class="identifier">T</span><span class="special">::</span><span class="identifier">AType</span><span class="special">::</span><span class="identifier">BType</span><span class="special">::</span><span class="identifier">CType</span><span class="special">::</span><span class="identifier">FindType</span><span class="special">,</span>
  471. <span class="keyword">int</span>
  472. <span class="special">&gt;</span>
  473. </pre>
  474. <p>
  475. But this fails with a compiler error if there is no such nested type, and that
  476. is exactly what we do not want in our compile-time metaprogramming code.
  477. </p>
  478. <p>
  479. In the above metafunction we are asking whether or not FindType has a static
  480. member data element called 'MyData', and the result will be 'false' if either
  481. FindType does not exist or if it does exist but does not have a static member
  482. data of type 'int' called 'MyData'. In neither situation will we produce a
  483. compiler error.
  484. </p>
  485. <p>
  486. We may also be interested in ascertaining whether the deeply nested type 'FindType'
  487. actually exists. Our metafunction, using BOOST_TTI_MEMBER_TYPE and repeating
  488. our macros from above, could be:
  489. </p>
  490. <pre class="programlisting"><span class="identifier">BOOST_TTI_MEMBER_TYPE</span><span class="special">(</span><span class="identifier">FindType</span><span class="special">)</span>
  491. <span class="identifier">BOOST_TTI_MEMBER_TYPE</span><span class="special">(</span><span class="identifier">AType</span><span class="special">)</span>
  492. <span class="identifier">BOOST_TTI_MEMBER_TYPE</span><span class="special">(</span><span class="identifier">BType</span><span class="special">)</span>
  493. <span class="identifier">BOOST_TTI_MEMBER_TYPE</span><span class="special">(</span><span class="identifier">CType</span><span class="special">)</span>
  494. <span class="identifier">BOOST_TTI_HAS_TYPE</span><span class="special">(</span><span class="identifier">FindType</span><span class="special">)</span>
  495. <span class="identifier">has_type_FindType</span>
  496. <span class="special">&lt;</span>
  497. <span class="keyword">typename</span>
  498. <span class="identifier">member_type_CType</span>
  499. <span class="special">&lt;</span>
  500. <span class="keyword">typename</span>
  501. <span class="identifier">member_type_BType</span>
  502. <span class="special">&lt;</span>
  503. <span class="keyword">typename</span>
  504. <span class="identifier">member_type_AType</span>
  505. <span class="special">&lt;</span>
  506. <span class="identifier">T</span>
  507. <span class="special">&gt;::</span><span class="identifier">type</span>
  508. <span class="special">&gt;::</span><span class="identifier">type</span>
  509. <span class="special">&gt;::</span><span class="identifier">type</span>
  510. <span class="special">&gt;</span>
  511. </pre>
  512. <p>
  513. But this duplicates much of our code when we generated the 'MyFindType' typedef.
  514. Instead we use the functionality already provided by 'boost::tti::valid_member_type'.
  515. Using this functionality with our 'MyFindType' type above we create the nullary
  516. metafunction:
  517. </p>
  518. <pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">tti</span><span class="special">::</span><span class="identifier">valid_member_type</span>
  519. <span class="special">&lt;</span>
  520. <span class="identifier">MyFindType</span>
  521. <span class="special">&gt;</span>
  522. </pre>
  523. <p>
  524. directly instead of replicating the same functionality with our 'has_type_FindType'
  525. metafunction.
  526. </p>
  527. </div>
  528. <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
  529. <td align="left"></td>
  530. <td align="right"><div class="copyright-footer">Copyright &#169; 2011-2013 Tropic Software
  531. East Inc<p>
  532. Distributed under the Boost Software License, Version 1.0. (See accompanying
  533. 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>)
  534. </p>
  535. </div></td>
  536. </tr></table>
  537. <hr>
  538. <div class="spirit-nav">
  539. <a accesskey="p" href="tti_detail_has_function.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="tti_func_sig.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
  540. </div>
  541. </body>
  542. </html>