| 1 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0.1 Transitional//EN"> | 
|---|
| 2 |  | 
|---|
| 3 | <html> | 
|---|
| 4 | <head> | 
|---|
| 5 | <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> | 
|---|
| 6 | <title>Boost.MultiIndex Documentation - Compiler specifics</title> | 
|---|
| 7 | <link rel="stylesheet" href="style.css" type="text/css"> | 
|---|
| 8 | <link rel="start" href="index.html"> | 
|---|
| 9 | <link rel="prev" href="reference/key_extraction.html"> | 
|---|
| 10 | <link rel="up" href="index.html"> | 
|---|
| 11 | <link rel="next" href="performance.html"> | 
|---|
| 12 | </head> | 
|---|
| 13 |  | 
|---|
| 14 | <body> | 
|---|
| 15 | <h1><img src="../../../boost.png" alt="boost.png (6897 bytes)" align= | 
|---|
| 16 | "middle" width="277" height="86">Boost.MultiIndex Compiler specifics</h1> | 
|---|
| 17 |  | 
|---|
| 18 | <div class="prev_link"><a href="reference/key_extraction.html"><img src="prev.gif" alt="key extraction" border="0"><br> | 
|---|
| 19 | Key extraction | 
|---|
| 20 | </a></div> | 
|---|
| 21 | <div class="up_link"><a href="index.html"><img src="up.gif" alt="index" border="0"><br> | 
|---|
| 22 | Index | 
|---|
| 23 | </a></div> | 
|---|
| 24 | <div class="next_link"><a href="performance.html"><img src="next.gif" alt="performance" border="0"><br> | 
|---|
| 25 | Performance | 
|---|
| 26 | </a></div><br clear="all" style="clear: all;"> | 
|---|
| 27 |  | 
|---|
| 28 | <hr> | 
|---|
| 29 |  | 
|---|
| 30 | <p> | 
|---|
| 31 | Boost.MultiIndex has been tried in different compilers, with | 
|---|
| 32 | various degrees of success. We list the limitations encountered, | 
|---|
| 33 | along with suitable workarounds when available. | 
|---|
| 34 | </p> | 
|---|
| 35 |  | 
|---|
| 36 | <h2>Contents</h2> | 
|---|
| 37 |  | 
|---|
| 38 | <ul> | 
|---|
| 39 |   <li><a href="#bcb_64">Borland C++ Builder 6.4 and later</a></li> | 
|---|
| 40 |   <li><a href="#comeau_433_win_vc7_71">Comeau C/C++ 4.3.3 for Windows (VC++ 7.0/7.1 backend)</a></li> | 
|---|
| 41 |   <li><a href="#compaq_65">Compaq C++ 6.5-042 for Tru64 UNIX and later</a></li> | 
|---|
| 42 |   <li> | 
|---|
| 43 |     <a href="#gcc_32">GNU GCC 3.2 and later</a> | 
|---|
| 44 |     <ul> | 
|---|
| 45 |       <li><a href="#gcc_tru64">GNU GCC for Tru64 UNIX</a></li> | 
|---|
| 46 |       <li><a href="#gcc_4_darwin">Darwin GCC 4.0</a></li> | 
|---|
| 47 |     </ul> | 
|---|
| 48 |   </li> | 
|---|
| 49 |   <li><a href="#acc_612">HP aC++ A.06.12 for HP-UX</a></li> | 
|---|
| 50 |   <li><a href="#va_60">IBM VisualAge C++ V6.0 for AIX</a></li> | 
|---|
| 51 |   <li><a href="#intel_90_lin">Intel C++ Compiler for Linux 9.0 and later</a></li> | 
|---|
| 52 |   <li><a href="#intel_7x_win">Intel C++ Compiler for Windows 32-bit 7.0/7.1</a></li> | 
|---|
| 53 |   <li><a href="#intel_80_win">Intel C++ Compiler for Windows 32-bit 8.0 and later</a></li> | 
|---|
| 54 |   <li><a href="#intel_em64t_91_win">Intel C++ Compiler Extended Memory 64 Technology 9.1 for Windows</a></li> | 
|---|
| 55 |   <li><a href="#cw_83">Metrowerks CodeWarrior 8.3</a></li> | 
|---|
| 56 |   <li><a href="#cw_9x">Metrowerks CodeWarrior 9 and later</a></li> | 
|---|
| 57 |   <li> | 
|---|
| 58 |     <a href="#msvc_60">Microsoft Visual C++ 6.0 Service Pack 5</a> | 
|---|
| 59 |     <ul> | 
|---|
| 60 |       <li><a href="#msvc_60_stlport_453">Microsoft Visual C++ 6.0 Service Pack 5 + STLport 4.5.3 and later</a></li> | 
|---|
| 61 |     </ul> | 
|---|
| 62 |   </li> | 
|---|
| 63 |   <li> | 
|---|
| 64 |     <a href="#msvc_70">Microsoft Visual C++ 7.0</a> | 
|---|
| 65 |     <ul> | 
|---|
| 66 |       <li><a href="#msvc_70_stlport_501">Microsoft Visual C++ 7.0 + STLport 5.0.1</a></li> | 
|---|
| 67 |     </ul> | 
|---|
| 68 |   </li> | 
|---|
| 69 |   <li> | 
|---|
| 70 |     <a href="#msvc_71">Microsoft Visual C++ 7.1</a> | 
|---|
| 71 |     <ul> | 
|---|
| 72 |       <li><a href="#msvc_71_stlport_462">Microsoft Visual C++ 7.1 + STLport 4.6.2</a></li> | 
|---|
| 73 |     </ul> | 
|---|
| 74 |   </li> | 
|---|
| 75 |   <li> | 
|---|
| 76 |     <a href="#msvc_80">Microsoft Visual C++ 8.0</a> | 
|---|
| 77 |     <ul> | 
|---|
| 78 |       <li><a href="#msvc_80_stlport_501">Microsoft Visual C++ 8.0 + STLport 5.0.1</a></li> | 
|---|
| 79 |     </ul> | 
|---|
| 80 |   </li> | 
|---|
| 81 |   <li><a href="#msvc_80_x86_amd64">Microsoft Visual C++ 8.0 x64 cross-compiler</a></li> | 
|---|
| 82 |   <li><a href="#sun_11">Sun Studio 11 for Solaris</a></li> | 
|---|
| 83 |   <li><a href="#portability">Portability techniques</a> | 
|---|
| 84 |     <ul> | 
|---|
| 85 |       <li><a href="#member_offset">Use of <code>member_offset</code></a></li> | 
|---|
| 86 |       <li><a href="#mem_fun_explicit">Use of <code>const_mem_fun_explicit</code> and | 
|---|
| 87 |         <code>mem_fun_explicit</code></a></li> | 
|---|
| 88 |       <li><a href="#composite_key_no_pts"><code>composite_key</code> in compilers | 
|---|
| 89 |         without partial template specialization</a></li> | 
|---|
| 90 |       <li><a href="#symbol_reduction">Reduction of symbol name lengths</a> | 
|---|
| 91 |         <ul> | 
|---|
| 92 |           <li><a href="#argument_limitation">Limitation of maximum number of arguments</a></li> | 
|---|
| 93 |           <li><a href="#type_hiding">Type hiding</a></li> | 
|---|
| 94 |         </ul> | 
|---|
| 95 |       </li> | 
|---|
| 96 |     </ul> | 
|---|
| 97 |   </li> | 
|---|
| 98 | </ul> | 
|---|
| 99 |  | 
|---|
| 100 | <h2><a name="bcb_64">Borland C++ Builder 6.4 and later</a></h2> | 
|---|
| 101 |  | 
|---|
| 102 | <p> | 
|---|
| 103 | Currently, Boost.MultiIndex cannot be used with any of BCB 6.4 up to BCB 2006. | 
|---|
| 104 | The number of problems encountered during the tests makes it unlikely that | 
|---|
| 105 | future versions of the library can be made to work under these compilers. | 
|---|
| 106 | </p> | 
|---|
| 107 |  | 
|---|
| 108 | <h2><a name="comeau_433_win_vc7_71">Comeau C/C++ 4.3.3 for Windows (VC++ 7.0/7.1 backend)</a></h2> | 
|---|
| 109 |  | 
|---|
| 110 | <p> | 
|---|
| 111 | No problems have been detected with this compiler. The library fails to compile, | 
|---|
| 112 | however, when Microsoft Visual C++ 6.0 is used as the backend. | 
|---|
| 113 | </p> | 
|---|
| 114 |  | 
|---|
| 115 | <h2><a name="compaq_65">Compaq C++ 6.5-042 for Tru64 UNIX and later</a></h2> | 
|---|
| 116 |  | 
|---|
| 117 | <p> | 
|---|
| 118 | No problems have been detected with this compiler. Versions 6.5-042, | 
|---|
| 119 | 7.1-005 and 7.1-006 have been tested. | 
|---|
| 120 | </p> | 
|---|
| 121 |  | 
|---|
| 122 | <h2><a name="gcc_32">GNU GCC 3.2 and later</a></h2> | 
|---|
| 123 |  | 
|---|
| 124 | <p> | 
|---|
| 125 | No problems have been detected with several versions of this compiler | 
|---|
| 126 | starting from 3.2. The following versions have been explicitly tested: | 
|---|
| 127 | <ul> | 
|---|
| 128 |   <li>GCC 3.2 20020927 (prerelease) under Cygwin 1.5.7,</li> | 
|---|
| 129 |   <li>GCC 3.2.3 under Linux,</li> | 
|---|
| 130 |   <li>GCC 3.3.5 (qnx-nto) under QNX 6.3.0 and QNX 6.3.2, | 
|---|
| 131 |   <li>GCC 3.3.6 under Linux,</li> | 
|---|
| 132 |   <li>GCC 3.4.2 (mingw-special) under Win32, | 
|---|
| 133 |     (mingw-special) + STLport 5.0.1 under Win32,</li> | 
|---|
| 134 |   <li>GCC 3.4.3 under Solaris,</li> | 
|---|
| 135 |   <li>GCC 3.4.4 under Linux and Tru64 (see <a href="#gcc_tru64">below</a>),</li> | 
|---|
| 136 |   <li>GCC 3.4.5 under Linux and Linux x86-64, (mingw-special) under Win32, | 
|---|
| 137 |     (mingw-special) + STLport 5.0.1 under Win32, | 
|---|
| 138 |     (mingw-special) + STLport 5.1.0 under Win32,</li> | 
|---|
| 139 |   <li>GCC 4.0.1 (Apple build 5250) under Mac OS,</li> | 
|---|
| 140 |   <li>GCC 4.0.3 under Linux and Tru64 (see <a href="#gcc_tru64">below</a>),</li> | 
|---|
| 141 |   <li>GCC 4.1.0 under Linux and Linux x86-64,</li> | 
|---|
| 142 |   <li>GCC 4.1.1 (OpenPKG-2-STABLE) under Solaris.</li> | 
|---|
| 143 | </ul> | 
|---|
| 144 | Boost.MultiIndex does not work with versions 3.1 and prior of GCC. | 
|---|
| 145 | </p> | 
|---|
| 146 |  | 
|---|
| 147 | <h3><a name="gcc_tru64">GNU GCC for Tru64 UNIX</a></h3> | 
|---|
| 148 |  | 
|---|
| 149 | <p> | 
|---|
| 150 | On this platform, GCC is not able to handle debug symbol names whose length | 
|---|
| 151 | exceeds 32,768 bytes, resulting in the error <code>mips-tfile, ... string | 
|---|
| 152 | too big</code>. You may encounter this issue with heavily templatized | 
|---|
| 153 | code like Boost.MultiIndex, which typically produces long symbol names. The problem | 
|---|
| 154 | can be overcome by omitting the compiler option <code>-g</code> (generate debugging | 
|---|
| 155 | information.) Alternatively, consult the section on | 
|---|
| 156 | <a href="#symbol_reduction">reduction of symbol name lengths</a> for various | 
|---|
| 157 | applicable workarounds. | 
|---|
| 158 | </p> | 
|---|
| 159 |  | 
|---|
| 160 | <h3><a name="gcc_4_darwin">Darwin GCC 4.0</a></h3> | 
|---|
| 161 |  | 
|---|
| 162 | <p> | 
|---|
| 163 | Build 4061 of GCC 4.0, shipped with Darwin 8.2 and prior (Mac OS X 10.4.2 and | 
|---|
| 164 | prior), corresponds to a prerelease version of GNU GCC 4.0.0 which introduces | 
|---|
| 165 | a <a href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17435">regression bug</a> | 
|---|
| 166 | related to binding of references to temporary objects. This bug precludes the | 
|---|
| 167 | usage of Boost.MultiIndex | 
|---|
| 168 | <a href="tutorial/debug.html#invariant_check">invariant-checking mode</a>; other | 
|---|
| 169 | than this, Boost.MultiIndex works correctly. | 
|---|
| 170 | The bug is corrected in GCC 4.0 Apple build 5026, which is in sync with the official | 
|---|
| 171 | release of GNU GCC 4.0.0, so the invariant-checking mode is available from this | 
|---|
| 172 | upgrade. | 
|---|
| 173 | </p> | 
|---|
| 174 |  | 
|---|
| 175 | <h2><a name="acc_612">HP aC++ A.06.12 for HP-UX</a></h2> | 
|---|
| 176 |  | 
|---|
| 177 | <p> | 
|---|
| 178 | No problems have been detected with this compiler. | 
|---|
| 179 | </p> | 
|---|
| 180 |  | 
|---|
| 181 | <h2><a name="va_60">IBM VisualAge C++ V6.0 for AIX</a></h2> | 
|---|
| 182 |  | 
|---|
| 183 | <p> | 
|---|
| 184 | <b>Note:</b> This information was last checked for Boost 1.33.1. There is a | 
|---|
| 185 | possibility that changes in Boost since that release have | 
|---|
| 186 | caused problems with this platform. | 
|---|
| 187 | </p> | 
|---|
| 188 |  | 
|---|
| 189 | <blockquote><hr></blockquote> | 
|---|
| 190 |  | 
|---|
| 191 | <p> | 
|---|
| 192 | <a href="reference/key_extraction.html#member"><code>member</code></a> not supported, | 
|---|
| 193 | refer to the section on | 
|---|
| 194 | <a href="#member_offset">use of <code>member_offset</code></a> for workarounds. | 
|---|
| 195 | <code>member_offset</code> causes the compiler to emit warnings about the | 
|---|
| 196 | use of <code>offsetof</code> with non-POD types: these warnings can be suppressed | 
|---|
| 197 | by setting the compiler option <code>-qsuppress=1540-1281</code>, or, alternatively, | 
|---|
| 198 | by inserting the following preprocessor directive: | 
|---|
| 199 | </p> | 
|---|
| 200 |  | 
|---|
| 201 | <blockquote><pre> | 
|---|
| 202 | <span class=preprocessor>#pragma</span> <span class=identifier>info</span><span class=special>(</span><span class=identifier>nolan</span><span class=special>)</span> | 
|---|
| 203 | </pre></blockquote> | 
|---|
| 204 |  | 
|---|
| 205 | <p> | 
|---|
| 206 | This latter pragma, however, may also eliminate other warnings not related | 
|---|
| 207 | to the use of <code>offsetof</code>. | 
|---|
| 208 | </p> | 
|---|
| 209 |  | 
|---|
| 210 | <blockquote><hr></blockquote> | 
|---|
| 211 |  | 
|---|
| 212 | <p> | 
|---|
| 213 | Serialization capabilities are not available as Boost.Serialization is not | 
|---|
| 214 | supported on this platform. | 
|---|
| 215 | </p> | 
|---|
| 216 |  | 
|---|
| 217 | <h2><a name="intel_90_lin">Intel C++ Compiler for Linux 9.0 and later</a></h2> | 
|---|
| 218 |  | 
|---|
| 219 | <p> | 
|---|
| 220 | No problems have been detected with this compilers from version 9.0. | 
|---|
| 221 | </p> | 
|---|
| 222 |  | 
|---|
| 223 | <h2><a name="intel_7x_win">Intel C++ Compiler for Windows 32-bit 7.0/7.1</a></h2> | 
|---|
| 224 |  | 
|---|
| 225 | <p> | 
|---|
| 226 | <a href="reference/key_extraction.html#member"><code>member</code></a> not supported, | 
|---|
| 227 | refer to the section on | 
|---|
| 228 | <a href="#member_offset">use of <code>member_offset</code></a> for workarounds. | 
|---|
| 229 | </p> | 
|---|
| 230 |  | 
|---|
| 231 | <blockquote><hr></blockquote> | 
|---|
| 232 |  | 
|---|
| 233 | <p> | 
|---|
| 234 | When used on top of MSVC++ 7.0 or prior, argument dependent lookup is | 
|---|
| 235 | disabled by default. This will cause problems with many Boost libraries, | 
|---|
| 236 | and in particular with the serialization part of Boost.MultiIndex. | 
|---|
| 237 | Argument dependent lookup is enabled by adding | 
|---|
| 238 | <code>/Qoption,c,--arg_dep_lookup</code> to the project options. | 
|---|
| 239 | </p> | 
|---|
| 240 |  | 
|---|
| 241 | <h2><a name="intel_80_win">Intel C++ Compiler for Windows 32-bit 8.0 and later</a></h2> | 
|---|
| 242 |  | 
|---|
| 243 | <p> | 
|---|
| 244 | When used on top of MSVC++ 7.0 or prior, argument dependent lookup is | 
|---|
| 245 | disabled by default. This will cause problems with many Boost libraries, | 
|---|
| 246 | and in particular with the serialization part of Boost.MultiIndex. | 
|---|
| 247 | Argument dependent lookup is enabled by adding | 
|---|
| 248 | <code>/Qoption,c,--arg_dep_lookup</code> to the project options. | 
|---|
| 249 | Other than this, Boost.MultiIndex works without problems. Compiler versions | 
|---|
| 250 | from 8.0 to 9.1 have been tested. | 
|---|
| 251 | </p> | 
|---|
| 252 |  | 
|---|
| 253 | <h2><a name="intel_em64t_91_win">Intel C++ Compiler Extended Memory 64 Technology 9.1 for Windows</a></h2> | 
|---|
| 254 |  | 
|---|
| 255 | <p> | 
|---|
| 256 | No problems have been detected with this compiler. | 
|---|
| 257 | </p> | 
|---|
| 258 |  | 
|---|
| 259 | <h2><a name="cw_83">Metrowerks CodeWarrior 8.3</a></h2> | 
|---|
| 260 |  | 
|---|
| 261 | <p> | 
|---|
| 262 | Predefined key extractors instantiated on a given type do not accept | 
|---|
| 263 | objects of derived types. For instance: | 
|---|
| 264 | </p> | 
|---|
| 265 |  | 
|---|
| 266 | <blockquote><pre> | 
|---|
| 267 | <span class=keyword>struct</span> <span class=identifier>base</span><span class=special>{};</span> | 
|---|
| 268 | <span class=keyword>struct</span> <span class=identifier>derived</span><span class=special>:</span><span class=keyword>public</span> <span class=identifier>base</span><span class=special>{};</span> | 
|---|
| 269 | <span class=special>...</span> | 
|---|
| 270 |  | 
|---|
| 271 | <span class=identifier>identity</span><span class=special><</span><span class=identifier>base</span><span class=special>></span> <span class=identifier>key_extractor</span><span class=special>;</span> | 
|---|
| 272 | <span class=identifier>derived</span>        <span class=identifier>x</span><span class=special>;</span> | 
|---|
| 273 |  | 
|---|
| 274 | <span class=comment>// not accepted by this compiler: an explicit cast to base is required</span> | 
|---|
| 275 | <span class=identifier>key_extractor</span><span class=special>(</span><span class=identifier>x</span><span class=special>);</span> | 
|---|
| 276 | </pre></blockquote> | 
|---|
| 277 |  | 
|---|
| 278 | <p> | 
|---|
| 279 | Other than this, Boost.MultiIndex works without problems under the | 
|---|
| 280 | two operating systems tested: Mac OS and Windows. | 
|---|
| 281 | </p> | 
|---|
| 282 |  | 
|---|
| 283 | <h2><a name="cw_9x">Metrowerks CodeWarrior 9 and later</a></h2> | 
|---|
| 284 |  | 
|---|
| 285 | <p> | 
|---|
| 286 | Boost.MultiIndex works correctly with versions of this compiler from 9.0 to | 
|---|
| 287 | 9.5, under the two operating systems tested: Mac OS and Windows. | 
|---|
| 288 | </p> | 
|---|
| 289 |  | 
|---|
| 290 | <h2><a name="msvc_60">Microsoft Visual C++ 6.0 Service Pack 5</a></h2> | 
|---|
| 291 |  | 
|---|
| 292 | <p> | 
|---|
| 293 | <a href="reference/key_extraction.html#member"><code>member</code></a> not supported, | 
|---|
| 294 | refer to the section on | 
|---|
| 295 | <a href="#member_offset">use of <code>member_offset</code></a> for workarounds. | 
|---|
| 296 | </p> | 
|---|
| 297 |  | 
|---|
| 298 | <p> | 
|---|
| 299 | <a href="reference/key_extraction.html#const_mem_fun"><code>const_mem_fun</code></a> and | 
|---|
| 300 | <a href="reference/key_extraction.html#mem_fun"><code>mem_fun</code></a> | 
|---|
| 301 | not supported, refer to the section on | 
|---|
| 302 | <a href="#mem_fun_explicit">use of <code>const_mem_fun_explicit</code> and | 
|---|
| 303 | <code>mem_fun_explicit</code></a> for workarounds. | 
|---|
| 304 | </p> | 
|---|
| 305 |  | 
|---|
| 306 | <blockquote><hr></blockquote> | 
|---|
| 307 |  | 
|---|
| 308 | <p> | 
|---|
| 309 | No support for <a href="reference/multi_index_container.html#index_retrieval">index retrieval</a> | 
|---|
| 310 | and <a href="reference/multi_index_container.html#projection">projection</a> | 
|---|
| 311 | nested types and member functions: | 
|---|
| 312 | <ul> | 
|---|
| 313 |   <li><code>nth_index</code>,</li> | 
|---|
| 314 |   <li><code>index</code>,</li> | 
|---|
| 315 |   <li><code>nth_index_iterator</code>,</li> | 
|---|
| 316 |   <li><code>nth_index_const_iterator</code>,</li> | 
|---|
| 317 |   <li><code>index_iterator</code>,</li> | 
|---|
| 318 |   <li><code>index_const_iterator</code>,</li> | 
|---|
| 319 |   <li><code>get</code>,</li> | 
|---|
| 320 |   <li><code>project</code>.</li> | 
|---|
| 321 | </ul> | 
|---|
| 322 | You can use instead their global equivalents. Also, this compiler does not | 
|---|
| 323 | implement argument dependent lookup, so you might need to explicitly qualify | 
|---|
| 324 | these global names with <code>::boost::multi_index</code>. | 
|---|
| 325 | </p> | 
|---|
| 326 |  | 
|---|
| 327 | <blockquote><hr></blockquote> | 
|---|
| 328 |  | 
|---|
| 329 | <p> | 
|---|
| 330 | <code>boost::multi_index::multi_index_container</code> is imported to | 
|---|
| 331 | <code>namespace boost</code> by means of a <code>using</code> declaration. | 
|---|
| 332 | MSVC++ 6.0, however, does not properly handle this import. So, instead of | 
|---|
| 333 | writing: | 
|---|
| 334 | </p> | 
|---|
| 335 |  | 
|---|
| 336 | <blockquote><pre> | 
|---|
| 337 | <span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index_container</span><span class=special><...></span> | 
|---|
| 338 | </pre></blockquote> | 
|---|
| 339 |  | 
|---|
| 340 | <p> | 
|---|
| 341 | use the following: | 
|---|
| 342 | </p> | 
|---|
| 343 |  | 
|---|
| 344 | <blockquote><pre> | 
|---|
| 345 | <span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>multi_index_container</span><span class=special><...></span> | 
|---|
| 346 | </pre></blockquote> | 
|---|
| 347 |  | 
|---|
| 348 | <p> | 
|---|
| 349 | or else resort to a directive <code>using namespace boost::multi_index</code>. | 
|---|
| 350 | </p> | 
|---|
| 351 |  | 
|---|
| 352 | <blockquote><hr></blockquote> | 
|---|
| 353 |  | 
|---|
| 354 | <p> | 
|---|
| 355 | The lack of partial template specialization support in MSVC++ 6.0 | 
|---|
| 356 | results in some inconveniences when using <code>composite_key</code> that | 
|---|
| 357 | can be remedied as explained in | 
|---|
| 358 | <a href="#composite_key_no_pts">"<code>composite_key</code> | 
|---|
| 359 | in compilers without partial template specialization"</a>. | 
|---|
| 360 | </p> | 
|---|
| 361 |  | 
|---|
| 362 | <blockquote><hr></blockquote> | 
|---|
| 363 |  | 
|---|
| 364 | <p> | 
|---|
| 365 | Due to problems with function template ordering support, | 
|---|
| 366 | <a href="reference/key_extraction.html#composite_key_compare"><code>composite_key_compare</code></a> | 
|---|
| 367 | and related classes do not accept the notational variations of | 
|---|
| 368 | <code>operator()</code> where one of the operands is treated as if | 
|---|
| 369 | included into a tuple of length 1. As a result, the user cannot ever | 
|---|
| 370 | omit tuple enclosing when specifying the arguments of lookup operations | 
|---|
| 371 | involving composite keys. | 
|---|
| 372 | </p> | 
|---|
| 373 |  | 
|---|
| 374 | <blockquote><hr></blockquote> | 
|---|
| 375 |  | 
|---|
| 376 | <p> | 
|---|
| 377 | Predefined key extractors instantiated on a given type do not accept | 
|---|
| 378 | objects of derived types. For instance: | 
|---|
| 379 | </p> | 
|---|
| 380 |  | 
|---|
| 381 | <blockquote><pre> | 
|---|
| 382 | <span class=keyword>struct</span> <span class=identifier>base</span><span class=special>{};</span> | 
|---|
| 383 | <span class=keyword>struct</span> <span class=identifier>derived</span><span class=special>:</span><span class=keyword>public</span> <span class=identifier>base</span><span class=special>{};</span> | 
|---|
| 384 | <span class=special>...</span> | 
|---|
| 385 |  | 
|---|
| 386 | <span class=identifier>identity</span><span class=special><</span><span class=identifier>base</span><span class=special>></span> <span class=identifier>key_extractor</span><span class=special>;</span> | 
|---|
| 387 | <span class=identifier>derived</span>        <span class=identifier>x</span><span class=special>;</span> | 
|---|
| 388 |  | 
|---|
| 389 | <span class=comment>// not accepted by this compiler: an explicit cast to base is required</span> | 
|---|
| 390 | <span class=identifier>key_extractor</span><span class=special>(</span><span class=identifier>x</span><span class=special>);</span> | 
|---|
| 391 | </pre></blockquote> | 
|---|
| 392 |  | 
|---|
| 393 | <blockquote><hr></blockquote> | 
|---|
| 394 |  | 
|---|
| 395 | <p> | 
|---|
| 396 | MSVC++ 6.0 presents serious limitations for the maximum length of | 
|---|
| 397 | symbol names generated by the compiler, which might result in the | 
|---|
| 398 | linker error | 
|---|
| 399 | <code><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/html/lnk1179.asp">LNK1179</a>: | 
|---|
| 400 | invalid or corrupt file: duplicate comdat | 
|---|
| 401 | comdat</code>. To overcome this problem, consult the section on | 
|---|
| 402 | <a href="#symbol_reduction">reduction of symbol name lengths</a> for various | 
|---|
| 403 | applicable workarounds.  | 
|---|
| 404 | </p> | 
|---|
| 405 |  | 
|---|
| 406 | <blockquote><hr></blockquote> | 
|---|
| 407 |  | 
|---|
| 408 | <p> | 
|---|
| 409 | Under some circumstances, the compiler emits the error | 
|---|
| 410 | <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/html/C2587.asp"> | 
|---|
| 411 | <code>C2587</code></a><code>: '_U' : illegal use of local variable as | 
|---|
| 412 | default parameter</code>, inside the MSVC internal header | 
|---|
| 413 | <code><xlocnum></code>. | 
|---|
| 414 | This problem is a recurrent bug of the compiler, and has been reported in | 
|---|
| 415 | other unrelated libraries, like the | 
|---|
| 416 | <a href="../../../libs/graph/doc/table_of_contents.html">Boost Graph Library</a>, | 
|---|
| 417 | <a href="../../../libs/multi_array/doc/index.html">Boost.MultiArray</a>, | 
|---|
| 418 | <a href="../../../libs/regex/doc/index.html">Boost.Regex</a>, | 
|---|
| 419 | <a href="http://www.cgal.org/">CGAL</a> and | 
|---|
| 420 | <a href="http://www.mysql.com/downloads/api-mysql++.html">MySQL++</a>. | 
|---|
| 421 | The error is triggered, though not in a systematic manner, by the use | 
|---|
| 422 | of <code>multi_index_container</code> iterator constructor. Two workarounds exist: | 
|---|
| 423 | the first consists of avoiding this constructor and replacing | 
|---|
| 424 | code like: | 
|---|
| 425 | </p> | 
|---|
| 426 |  | 
|---|
| 427 | <blockquote><pre> | 
|---|
| 428 | <span class=identifier>multi_index_container</span><span class=special><...></span> <span class=identifier>s</span><span class=special>(</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>end</span><span class=special>());</span> | 
|---|
| 429 | </pre></blockquote> | 
|---|
| 430 |  | 
|---|
| 431 | <p> | 
|---|
| 432 | with equivalent operations: | 
|---|
| 433 | </p> | 
|---|
| 434 |  | 
|---|
| 435 | <blockquote><pre> | 
|---|
| 436 | <span class=identifier>multi_index_container</span><span class=special><...></span> <span class=identifier>s</span><span class=special>;</span> | 
|---|
| 437 | <span class=identifier>s</span><span class=special>.</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>end</span><span class=special>());</span> | 
|---|
| 438 | </pre></blockquote> | 
|---|
| 439 |  | 
|---|
| 440 | <p> | 
|---|
| 441 | The second workaround has not been confirmed by the author, but it is given | 
|---|
| 442 | on the Internet in connection with this error appearing in other libraries. | 
|---|
| 443 | Replace line 84 of <code><xlocnum></code> | 
|---|
| 444 |  | 
|---|
| 445 | <blockquote><pre> | 
|---|
| 446 |  <span class=preprocessor>#define</span> <span class=identifier>_VIRTUAL</span> <span class=keyword>virtual</span> | 
|---|
| 447 | </pre></blockquote> | 
|---|
| 448 |  | 
|---|
| 449 | <p> | 
|---|
| 450 | with the following: | 
|---|
| 451 | </p> | 
|---|
| 452 |  | 
|---|
| 453 | <blockquote><pre> | 
|---|
| 454 |  <span class=preprocessor>#define</span> <span class=identifier>_VIRTUAL</span> | 
|---|
| 455 | </pre></blockquote> | 
|---|
| 456 |  | 
|---|
| 457 | <p> | 
|---|
| 458 | <b>Warning</b>: it is not known whether this | 
|---|
| 459 | replacement can result in unexpected side effects in code implicitly | 
|---|
| 460 | using <code><xlocnum></code>. | 
|---|
| 461 | </p> | 
|---|
| 462 |  | 
|---|
| 463 | <blockquote><hr></blockquote> | 
|---|
| 464 |  | 
|---|
| 465 | <p> | 
|---|
| 466 | In general, the extensive use of templates by Boost.MultiIndex puts this compiler | 
|---|
| 467 | under severe stress, so that several internal limitations may be reached. | 
|---|
| 468 | The following measures can help alleviate these problems: | 
|---|
| 469 | <ul> | 
|---|
| 470 |   <li>Set the compiler option <code>/Zm</code> (Specify Memory Allocation Limit) | 
|---|
| 471 |     to increase the amount of memory available for compilation. Usual values for | 
|---|
| 472 |     this option range from 300 to 800.</li> | 
|---|
| 473 |   <li>If in debug mode, try switching from <code>/ZI</code> (Program Database for | 
|---|
| 474 |     Edit and Continue) to a less demanding type of debugging information | 
|---|
| 475 |     (<code>/Zi</code>, <code>/Z7</code> or <code>/Zd</code>.)</li> | 
|---|
| 476 |   <li>Play with the precompiled headers options. Usually, turning this feature | 
|---|
| 477 |     off yields the best results.</li> | 
|---|
| 478 |   <li>If the compiler emits the error | 
|---|
| 479 |     <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/html/c1055.asp"> | 
|---|
| 480 |     <code>C1055</code></a><code>: compiler limit : out of keys</code>, try | 
|---|
| 481 |     disabling the option <code>/Gm</code> (Enable Minimal Rebuild.) In these | 
|---|
| 482 |     cases, it is also beneficial to split the project into smaller | 
|---|
| 483 |     subprojects.</li> | 
|---|
| 484 | </ul> | 
|---|
| 485 | </p> | 
|---|
| 486 |  | 
|---|
| 487 | <h3> | 
|---|
| 488 | <a name="msvc_60_stlport_453">Microsoft Visual C++ 6.0 Service Pack 5 | 
|---|
| 489 | + STLport 4.5.3 and later</a> | 
|---|
| 490 | </h3> | 
|---|
| 491 |  | 
|---|
| 492 | <p> | 
|---|
| 493 | Boost.MultiIndex works for this configuration. The same limitations apply as | 
|---|
| 494 | in MSVC++ 6.0 with its original Dinkumware standard library. STLport 4.6.2 and | 
|---|
| 495 | 5.0.1 has also been confirmed to work correctly. | 
|---|
| 496 | </p> | 
|---|
| 497 |  | 
|---|
| 498 | <blockquote><hr></blockquote> | 
|---|
| 499 |  | 
|---|
| 500 | <p> | 
|---|
| 501 | It is not possible to use the serialization capabilities of Boost.MultiIndex | 
|---|
| 502 | along with the dynamic version of STLport, as some linking errors result. | 
|---|
| 503 | Use instead the static version of STLport. This bug is fixed in STLport 5.0. | 
|---|
| 504 | </p> | 
|---|
| 505 |  | 
|---|
| 506 | <h2><a name="msvc_70">Microsoft Visual C++ 7.0</a></h2> | 
|---|
| 507 |  | 
|---|
| 508 | <p> | 
|---|
| 509 | <a href="reference/key_extraction.html#member"><code>member</code></a> not supported, | 
|---|
| 510 | refer to the section on | 
|---|
| 511 | <a href="#member_offset">use of <code>member_offset</code></a> for workarounds. | 
|---|
| 512 | </p> | 
|---|
| 513 |  | 
|---|
| 514 | <blockquote><hr></blockquote> | 
|---|
| 515 |  | 
|---|
| 516 | <p> | 
|---|
| 517 | No support for <a href="reference/multi_index_container.html#index_retrieval">index retrieval</a> | 
|---|
| 518 | and <a href="reference/multi_index_container.html#projection">projection</a> | 
|---|
| 519 | nested types and member functions: | 
|---|
| 520 | <ul> | 
|---|
| 521 |   <li><code>nth_index</code>,</li> | 
|---|
| 522 |   <li><code>index</code>,</li> | 
|---|
| 523 |   <li><code>nth_index_iterator</code>,</li> | 
|---|
| 524 |   <li><code>nth_index_const_iterator</code>,</li> | 
|---|
| 525 |   <li><code>index_iterator</code>,</li> | 
|---|
| 526 |   <li><code>index_const_iterator</code>,</li> | 
|---|
| 527 |   <li><code>get</code>,</li> | 
|---|
| 528 |   <li><code>project</code>.</li> | 
|---|
| 529 | </ul> | 
|---|
| 530 | You can use instead their global equivalents. Also, this compiler does not | 
|---|
| 531 | implement argument dependent lookup, so you might need to explicitly qualify | 
|---|
| 532 | these global names with <code>::boost::multi_index</code>. | 
|---|
| 533 | </p> | 
|---|
| 534 |  | 
|---|
| 535 | <blockquote><hr></blockquote> | 
|---|
| 536 |  | 
|---|
| 537 | <p> | 
|---|
| 538 | <code>boost::multi_index::multi_index_container</code> is imported to | 
|---|
| 539 | <code>namespace boost</code> by means of a <code>using</code> declaration. | 
|---|
| 540 | MSVC++ 7.0, however, does not properly handle this import. So, instead of | 
|---|
| 541 | writing: | 
|---|
| 542 | </p> | 
|---|
| 543 |  | 
|---|
| 544 | <blockquote><pre> | 
|---|
| 545 | <span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index_container</span><span class=special><...></span> | 
|---|
| 546 | </pre></blockquote> | 
|---|
| 547 |  | 
|---|
| 548 | <p> | 
|---|
| 549 | use the following: | 
|---|
| 550 | </p> | 
|---|
| 551 |  | 
|---|
| 552 | <blockquote><pre> | 
|---|
| 553 | <span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>multi_index_container</span><span class=special><...></span> | 
|---|
| 554 | </pre></blockquote> | 
|---|
| 555 |  | 
|---|
| 556 | <p> | 
|---|
| 557 | or else resort to a directive <code>using namespace boost::multi_index</code>. | 
|---|
| 558 | </p> | 
|---|
| 559 |  | 
|---|
| 560 | <blockquote><hr></blockquote> | 
|---|
| 561 |  | 
|---|
| 562 | <p> | 
|---|
| 563 | The lack of partial template specialization support in MSVC++ 7.0 | 
|---|
| 564 | results in some inconveniences when using <code>composite_key</code> that | 
|---|
| 565 | can be remedied as explained in | 
|---|
| 566 | <a href="#composite_key_no_pts">"<code>composite_key</code> | 
|---|
| 567 | in compilers without partial template specialization"</a>. | 
|---|
| 568 | </p> | 
|---|
| 569 |  | 
|---|
| 570 | <blockquote><hr></blockquote> | 
|---|
| 571 |  | 
|---|
| 572 | <p> | 
|---|
| 573 | Due to problems with function template ordering support, | 
|---|
| 574 | <a href="reference/key_extraction.html#composite_key_compare"><code>composite_key_compare</code></a> | 
|---|
| 575 | and related classes do not accept the notational variations of | 
|---|
| 576 | <code>operator()</code> where one of the operands is treated as if | 
|---|
| 577 | included into a tuple of length 1. As a result, the user cannot ever | 
|---|
| 578 | omit tuple enclosing when specifying the arguments of lookup operations | 
|---|
| 579 | involving composite keys. | 
|---|
| 580 | </p> | 
|---|
| 581 |  | 
|---|
| 582 | <blockquote><hr></blockquote> | 
|---|
| 583 |  | 
|---|
| 584 | <p> | 
|---|
| 585 | Predefined key extractors instantiated on a given type do not accept | 
|---|
| 586 | objects of derived types. For instance: | 
|---|
| 587 | </p> | 
|---|
| 588 |  | 
|---|
| 589 | <blockquote><pre> | 
|---|
| 590 | <span class=keyword>struct</span> <span class=identifier>base</span><span class=special>{};</span> | 
|---|
| 591 | <span class=keyword>struct</span> <span class=identifier>derived</span><span class=special>:</span><span class=keyword>public</span> <span class=identifier>base</span><span class=special>{};</span> | 
|---|
| 592 | <span class=special>...</span> | 
|---|
| 593 |  | 
|---|
| 594 | <span class=identifier>identity</span><span class=special><</span><span class=identifier>base</span><span class=special>></span> <span class=identifier>key_extractor</span><span class=special>;</span> | 
|---|
| 595 | <span class=identifier>derived</span>        <span class=identifier>x</span><span class=special>;</span> | 
|---|
| 596 |  | 
|---|
| 597 | <span class=comment>// not accepted by this compiler: an explicit cast to base is required</span> | 
|---|
| 598 | <span class=identifier>key_extractor</span><span class=special>(</span><span class=identifier>x</span><span class=special>);</span> | 
|---|
| 599 | </pre></blockquote> | 
|---|
| 600 |  | 
|---|
| 601 | <h3><a name="msvc_70_stlport_501">Microsoft Visual C++ 7.0 + STLport 5.0.1</a></h3> | 
|---|
| 602 |  | 
|---|
| 603 | <p> | 
|---|
| 604 | Boost.MultiIndex works for this configuration. The same issues apply as in | 
|---|
| 605 | MSVC++ 7.0 with its original Dinkumware standard library.  | 
|---|
| 606 | </p> | 
|---|
| 607 |  | 
|---|
| 608 | <h2><a name="msvc_71">Microsoft Visual C++ 7.1</a></h2> | 
|---|
| 609 |  | 
|---|
| 610 | <p> | 
|---|
| 611 | Problems have been reported when compiling the library with the <code>/Gm</code> | 
|---|
| 612 | option (Enable Minimal Rebuild.) Seemingly, this is due to an | 
|---|
| 613 | internal defect of the compiler (see for instance | 
|---|
| 614 | <a href="http://lists.boost.org/boost-users/2004/02/5987.php"> | 
|---|
| 615 | this mention of a similar issue</a> in the Boost Users mailing list.) | 
|---|
| 616 | If <code>/Gm</code> is turned off, Boost.MultiIndex compiles and runs | 
|---|
| 617 | without further problems. | 
|---|
| 618 | </p> | 
|---|
| 619 |  | 
|---|
| 620 | <h3><a name="msvc_71_stlport_462">Microsoft Visual C++ 7.1 + STLport 4.6.2</a></h3> | 
|---|
| 621 |  | 
|---|
| 622 | <p> | 
|---|
| 623 | Boost.MultiIndex works for this configuration. The same issues apply as in | 
|---|
| 624 | MSVC++ 7.1 with its original Dinkumware standard library.  | 
|---|
| 625 | </p> | 
|---|
| 626 |  | 
|---|
| 627 | <h2><a name="msvc_80">Microsoft Visual C++ 8.0</a></h2> | 
|---|
| 628 |  | 
|---|
| 629 | <p> | 
|---|
| 630 | No problems have been detected with this compiler. | 
|---|
| 631 | </p> | 
|---|
| 632 |  | 
|---|
| 633 | <h3><a name="msvc_80_stlport_501">Microsoft Visual C++ 8.0 + STLport 5.0.1</a></h3> | 
|---|
| 634 |  | 
|---|
| 635 | <p> | 
|---|
| 636 | No problems have been detected with this configuration. | 
|---|
| 637 | </p> | 
|---|
| 638 |  | 
|---|
| 639 | <h2><a name="msvc_80_x86_amd64">Microsoft Visual C++ 8.0 x64 cross-compiler</a></h2> | 
|---|
| 640 |  | 
|---|
| 641 | <p> | 
|---|
| 642 | No problems have been detected with this compiler. | 
|---|
| 643 | </p> | 
|---|
| 644 |  | 
|---|
| 645 | <h2><a name="sun_11">Sun Studio 11 for Solaris</a></h2> | 
|---|
| 646 |  | 
|---|
| 647 | <p> | 
|---|
| 648 | No problems have been detected with this platform. The exact compiler version | 
|---|
| 649 | tested was Sun C++ 5.8 Patch 121017-03 2006/07/19. The option | 
|---|
| 650 | <code>-library=stlport4</code> was used to replace the default standard | 
|---|
| 651 | library with STLport. | 
|---|
| 652 | </p> | 
|---|
| 653 |  | 
|---|
| 654 | <h2><a name="portability">Portability techniques</a></h2> | 
|---|
| 655 |  | 
|---|
| 656 | <h3><a name="member_offset">Use of <code>member_offset</code></a></h3> | 
|---|
| 657 |  | 
|---|
| 658 | <p> | 
|---|
| 659 | The <code>member</code> key extractor poses some problems in compilers | 
|---|
| 660 | that do not properly support pointers to members as non-type | 
|---|
| 661 | template arguments, as indicated by the | 
|---|
| 662 | <a href="../../../libs/config/config.htm">Boost Configuration Library</a> | 
|---|
| 663 | defect macro <code>BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS</code>. | 
|---|
| 664 | The following compilers have been confirmed not | 
|---|
| 665 | to work correctly with <code>member</code>: | 
|---|
| 666 | <ul> | 
|---|
| 667 |   <li>MSVC++ 6.0/7.0,</li> | 
|---|
| 668 |   <li>Intel C++ 7.0/7.1 for Windows,</li> | 
|---|
| 669 |   <li>VisualAge 6.0 for AIX.</li> | 
|---|
| 670 | </ul> | 
|---|
| 671 | This program can help determine if your compiler | 
|---|
| 672 | properly supports pointers to members as non-type template parameters: | 
|---|
| 673 | </p> | 
|---|
| 674 |  | 
|---|
| 675 | <blockquote><pre> | 
|---|
| 676 | <span class=preprocessor>#include</span> <span class=special><</span><span class=identifier>iostream</span><span class=special>></span> | 
|---|
| 677 |  | 
|---|
| 678 | <span class=keyword>struct</span> <span class=identifier>pair</span> | 
|---|
| 679 | <span class=special>{</span> | 
|---|
| 680 |   <span class=keyword>int</span> <span class=identifier>x</span><span class=special>,</span><span class=identifier>y</span><span class=special>;</span> | 
|---|
| 681 |  | 
|---|
| 682 |   <span class=identifier>pair</span><span class=special>(</span><span class=keyword>int</span> <span class=identifier>x_</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>y_</span><span class=special>):</span><span class=identifier>x</span><span class=special>(</span><span class=identifier>x_</span><span class=special>),</span><span class=identifier>y</span><span class=special>(</span><span class=identifier>y_</span><span class=special>){}</span> | 
|---|
| 683 | <span class=special>};</span> | 
|---|
| 684 |  | 
|---|
| 685 | <span class=keyword>template</span><span class=special><</span><span class=keyword>int</span> <span class=identifier>pair</span><span class=special>::*</span> <span class=identifier>PtrToPairMember</span><span class=special>></span> | 
|---|
| 686 | <span class=keyword>struct</span> <span class=identifier>foo</span> | 
|---|
| 687 | <span class=special>{</span> | 
|---|
| 688 |   <span class=keyword>int</span> <span class=identifier>bar</span><span class=special>(</span><span class=identifier>pair</span><span class=special>&</span> <span class=identifier>p</span><span class=special>){</span><span class=keyword>return</span> <span class=identifier>p</span><span class=special>.*</span><span class=identifier>PtrToPairMember</span><span class=special>;}</span> | 
|---|
| 689 | <span class=special>};</span> | 
|---|
| 690 |  | 
|---|
| 691 | <span class=keyword>int</span> <span class=identifier>main</span><span class=special>()</span> | 
|---|
| 692 | <span class=special>{</span> | 
|---|
| 693 |   <span class=identifier>pair</span> <span class=identifier>p</span><span class=special>(</span><span class=number>0</span><span class=special>,</span><span class=number>1</span><span class=special>);</span> | 
|---|
| 694 |   <span class=identifier>foo</span><span class=special><&</span><span class=identifier>pair</span><span class=special>::</span><span class=identifier>x</span><span class=special>></span> <span class=identifier>fx</span><span class=special>;</span> | 
|---|
| 695 |   <span class=identifier>foo</span><span class=special><&</span><span class=identifier>pair</span><span class=special>::</span><span class=identifier>y</span><span class=special>></span> <span class=identifier>fy</span><span class=special>;</span> | 
|---|
| 696 |  | 
|---|
| 697 |   <span class=keyword>if</span><span class=special>(</span><span class=identifier>fx</span><span class=special>.</span><span class=identifier>bar</span><span class=special>(</span><span class=identifier>p</span><span class=special>)!=</span><span class=number>0</span><span class=special>||</span><span class=identifier>fy</span><span class=special>.</span><span class=identifier>bar</span><span class=special>(</span><span class=identifier>p</span><span class=special>)!=</span><span class=number>1</span><span class=special>)</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>cout</span><span class=special><<</span><span class=string>"KO"</span><span class=special><<</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>endl</span><span class=special>;</span> | 
|---|
| 698 |   <span class=keyword>else</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>cout</span><span class=special><<</span><span class=string>"OK"</span><span class=special><<</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>endl</span><span class=special>;</span> | 
|---|
| 699 |  | 
|---|
| 700 |   <span class=keyword>return</span> <span class=number>0</span><span class=special>;</span> | 
|---|
| 701 | <span class=special>}</span> | 
|---|
| 702 |  | 
|---|
| 703 | </pre></blockquote> | 
|---|
| 704 |  | 
|---|
| 705 | <p> | 
|---|
| 706 | If you find a compiler that does not pass the test, and for which | 
|---|
| 707 | <code>BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS</code> is <i>not</i> defined, | 
|---|
| 708 | please report to the Boost developers mailing list. | 
|---|
| 709 | </p> | 
|---|
| 710 | <p>To overcome this defect, a replacement utility | 
|---|
| 711 | <a href="reference/key_extraction.html#member_offset"><code>member_offset</code></a> | 
|---|
| 712 | has been provided that does the work of <code>member</code> at the | 
|---|
| 713 | expense of less convenient notation and the possibility of | 
|---|
| 714 | non-conformance with the standard. Please consult | 
|---|
| 715 | the reference for further information on <code>member_offset</code>. | 
|---|
| 716 | As an example of use, given the class | 
|---|
| 717 | </p> | 
|---|
| 718 |  | 
|---|
| 719 | <blockquote><pre> | 
|---|
| 720 | <span class=keyword>class</span> <span class=identifier>A</span> | 
|---|
| 721 | <span class=special>{</span> | 
|---|
| 722 |   <span class=keyword>int</span> <span class=identifier>x</span><span class=special>;</span> | 
|---|
| 723 | <span class=special>}</span> | 
|---|
| 724 | </pre></blockquote> | 
|---|
| 725 |  | 
|---|
| 726 | <p> | 
|---|
| 727 | the instantiation <code>member<A,int,&A::x></code> can be simulated then | 
|---|
| 728 | as <code>member_offset<A,int,offsetof(A,x)></code>. | 
|---|
| 729 | </p> | 
|---|
| 730 |  | 
|---|
| 731 | <p> | 
|---|
| 732 | For those writing portable code, Boost.MultiIndex provides the ternary macro | 
|---|
| 733 | <a href="reference/key_extraction.html#boost_multi_index_member"><code>BOOST_MULTI_INDEX_MEMBER</code></a>. | 
|---|
| 734 | Continuing with the example above, the | 
|---|
| 735 | expression | 
|---|
| 736 | </p> | 
|---|
| 737 |  | 
|---|
| 738 | <blockquote><pre> | 
|---|
| 739 | <span class=identifier>BOOST_MULTI_INDEX_MEMBER</span><span class=special>(</span><span class=identifier>A</span><span class=special>,</span><span class=keyword>int</span><span class=special>,</span><span class=identifier>x</span><span class=special>)</span> | 
|---|
| 740 | </pre></blockquote> | 
|---|
| 741 |  | 
|---|
| 742 | <p> | 
|---|
| 743 | expands by default to | 
|---|
| 744 | </p> | 
|---|
| 745 |  | 
|---|
| 746 | <blockquote><pre> | 
|---|
| 747 | <span class=identifier>member</span><span class=special><</span><span class=identifier>A</span><span class=special>,</span><span class=keyword>int</span><span class=special>,&</span><span class=identifier>A</span><span class=special>::</span><span class=identifier>x</span><span class=special>></span> | 
|---|
| 748 | </pre></blockquote> | 
|---|
| 749 |  | 
|---|
| 750 | <p> | 
|---|
| 751 | or alternatively to | 
|---|
| 752 | </p> | 
|---|
| 753 |  | 
|---|
| 754 | <blockquote><pre> | 
|---|
| 755 | <span class=identifier>member_offset</span><span class=special><</span><span class=identifier>A</span><span class=special>,</span><span class=keyword>int</span><span class=special>,</span><span class=identifier>offsetof</span><span class=special>(</span><span class=identifier>A</span><span class=special>,</span><span class=identifier>x</span><span class=special>)></span> | 
|---|
| 756 | </pre></blockquote> | 
|---|
| 757 |  | 
|---|
| 758 | <p> | 
|---|
| 759 | if <code>BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS</code> is defined. | 
|---|
| 760 | </p> | 
|---|
| 761 |  | 
|---|
| 762 | <h3><a name="mem_fun_explicit">Use of <code>const_mem_fun_explicit</code> and | 
|---|
| 763 | <code>mem_fun_explicit</code></a></h3> | 
|---|
| 764 |  | 
|---|
| 765 | <p> | 
|---|
| 766 | MSVC++ 6.0 has problems with <code>const</code> member functions as non-type | 
|---|
| 767 | template parameters, and thus does not accept the <code>const_mem_fun</code> | 
|---|
| 768 | key extractor. A simple workaround, fortunately, has been found, consisting | 
|---|
| 769 | in specifying the <i>type</i> of these pointers as an additional template | 
|---|
| 770 | parameter. The alternative | 
|---|
| 771 | <a href="reference/key_extraction.html#const_mem_fun_explicit"><code>const_mem_fun_explicit</code></a> | 
|---|
| 772 | extractor adopts this solution; for instance, given the type | 
|---|
| 773 | </p> | 
|---|
| 774 |  | 
|---|
| 775 | <blockquote><pre> | 
|---|
| 776 | <span class=keyword>struct</span> <span class=identifier>A</span> | 
|---|
| 777 | <span class=special>{</span> | 
|---|
| 778 |   <span class=keyword>int</span> <span class=identifier>f</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span> | 
|---|
| 779 | <span class=special>};</span> | 
|---|
| 780 | </pre></blockquote> | 
|---|
| 781 |  | 
|---|
| 782 | <p> | 
|---|
| 783 | the extractor <code>const_mem_fun<A,int,&A::f></code> can be replaced by | 
|---|
| 784 | <code>const_mem_fun_explicit<A,int,int (A::*)()const,&A::f></code>. A similar | 
|---|
| 785 | <code>mem_fun_explicit</code> class template is provided for non-constant | 
|---|
| 786 | member functions. | 
|---|
| 787 | </p> | 
|---|
| 788 |  | 
|---|
| 789 | <p> | 
|---|
| 790 | If you are writing cross-platform code, the selection of either key extractor | 
|---|
| 791 | is transparently handled by the macro | 
|---|
| 792 | <a href="reference/key_extraction.html#boost_multi_index_const_mem_fun"><code>BOOST_MULTI_INDEX_CONST_MEM_FUN</code></a>, | 
|---|
| 793 | so that | 
|---|
| 794 | </p> | 
|---|
| 795 |  | 
|---|
| 796 | <blockquote><pre> | 
|---|
| 797 | <span class=identifier>BOOST_MULTI_INDEX_CONST_MEM_FUN</span><span class=special>(</span><span class=identifier>A</span><span class=special>,</span><span class=keyword>int</span><span class=special>,</span><span class=identifier>f</span><span class=special>)</span> | 
|---|
| 798 | </pre></blockquote> | 
|---|
| 799 |  | 
|---|
| 800 | <p> | 
|---|
| 801 | expands by default to | 
|---|
| 802 | </p> | 
|---|
| 803 |  | 
|---|
| 804 | <blockquote><pre> | 
|---|
| 805 | <span class=identifier>const_mem_fun</span><span class=special><</span><span class=identifier>A</span><span class=special>,</span><span class=keyword>int</span><span class=special>,&</span><span class=identifier>A</span><span class=special>::</span><span class=identifier>f</span><span class=special>></span> | 
|---|
| 806 | </pre></blockquote> | 
|---|
| 807 |  | 
|---|
| 808 | <p> | 
|---|
| 809 | but resolves to  | 
|---|
| 810 | </p> | 
|---|
| 811 |  | 
|---|
| 812 | <blockquote><pre> | 
|---|
| 813 | <span class=identifier>const_mem_fun_explicit</span><span class=special><</span><span class=identifier>A</span><span class=special>,</span><span class=keyword>int</span><span class=special>,</span><span class=keyword>int</span> <span class=special>(</span><span class=identifier>A</span><span class=special>::*)()</span><span class=keyword>const</span><span class=special>,&</span><span class=identifier>A</span><span class=special>::</span><span class=identifier>f</span><span class=special>></span> | 
|---|
| 814 | </pre></blockquote> | 
|---|
| 815 |  | 
|---|
| 816 | <p> | 
|---|
| 817 | in MSVC++ 6.0. Non-<code>const</code> member functions are covered by | 
|---|
| 818 | <a href="reference/key_extraction.html#mem_fun_explicit"><code>mem_fun_explicit</code></a> | 
|---|
| 819 | and the macro | 
|---|
| 820 | <a href="reference/key_extraction.html#boost_multi_index_mem_fun"><code>BOOST_MULTI_INDEX_MEM_FUN</code></a>. | 
|---|
| 821 | </p> | 
|---|
| 822 |  | 
|---|
| 823 | <h3><a name="composite_key_no_pts"><code>composite_key</code> in compilers | 
|---|
| 824 | without partial template specialization</a></h3> | 
|---|
| 825 |  | 
|---|
| 826 | <p> | 
|---|
| 827 | When using <code>composite_key</code>s, lookup is performed by passing | 
|---|
| 828 | tuples of values: this ability is achieved by suitably specializing | 
|---|
| 829 | the class templates <code>std::equal_to</code>, <code>std::less</code>, | 
|---|
| 830 | <code>std::greater</code> and <code>boost::hash</code> for | 
|---|
| 831 | <a href="reference/key_extraction.html#composite_key_result"> | 
|---|
| 832 | <code>composite_key_result</code></a> instantiations so that they | 
|---|
| 833 | provide the appropriate overloads accepting tuples --and in the case | 
|---|
| 834 | of <code>std::less</code> and <code>std::greater</code>, also partial | 
|---|
| 835 | tuples where only the first components are specified. | 
|---|
| 836 | </p> | 
|---|
| 837 |  | 
|---|
| 838 | <p> | 
|---|
| 839 | In those compilers that do not support partial template specialization, | 
|---|
| 840 | these specializations cannot be provided, and so  | 
|---|
| 841 | tuple-based lookup is not available by default. In this case, | 
|---|
| 842 | <code>multi_index_container</code> instantiations using composite keys | 
|---|
| 843 | will work as expected, both for ordered and hashed indices, | 
|---|
| 844 | except that lookup operations will not accept tuples as an argument. | 
|---|
| 845 | For ordered indices, the most obvious workaround | 
|---|
| 846 | to this deficiency involves explicitly specifying the comparison | 
|---|
| 847 | predicate with | 
|---|
| 848 | <a href="reference/key_extraction.html#composite_key_compare"><code>composite_key_compare</code></a>; | 
|---|
| 849 | in the case of hashed indices we can use the analogous | 
|---|
| 850 | <a href="reference/key_extraction.html#composite_key_equal_to"><code>composite_key_equal_to</code></a> | 
|---|
| 851 | and | 
|---|
| 852 | <a href="reference/key_extraction.html#composite_key_hash"><code>composite_key_hash</code></a>. | 
|---|
| 853 | This substitution is tedious as the elementary components for all the constituent key extractors must | 
|---|
| 854 | be explicitly typed. For this reason, Boost.MultiIndex provides the following replacement | 
|---|
| 855 | class templates | 
|---|
| 856 | <ul> | 
|---|
| 857 |   <li><a href="reference/key_extraction.html#composite_key_result_equal_to"> | 
|---|
| 858 |     <code>composite_key_result_equal_to</code></a>,</li> | 
|---|
| 859 |   <li><a href="reference/key_extraction.html#composite_key_result_less"> | 
|---|
| 860 |     <code>composite_key_result_less</code></a>,</li> | 
|---|
| 861 |   <li><a href="reference/key_extraction.html#composite_key_result_greater"> | 
|---|
| 862 |     <code>composite_key_result_greater</code></a> and</li> | 
|---|
| 863 |   <li><a href="reference/key_extraction.html#composite_key_result_hash"> | 
|---|
| 864 |     <code>composite_key_result_hash</code></a>,</li> | 
|---|
| 865 | </ul> | 
|---|
| 866 | that act as the missing specializations of <code>std::equal_to</code>, <code>std::less</code>, | 
|---|
| 867 | <code>std::greater</code> and <code>boost::hash</code> for <code>composite_key_result</code>s. | 
|---|
| 868 | They can be used as follows: | 
|---|
| 869 | </p> | 
|---|
| 870 |  | 
|---|
| 871 | <blockquote><pre> | 
|---|
| 872 | <span class=keyword>typedef</span> <span class=identifier>composite_key</span><span class=special><</span> | 
|---|
| 873 |   <span class=identifier>phonebook_entry</span><span class=special>,</span> | 
|---|
| 874 |   <span class=identifier>member</span><span class=special><</span><span class=identifier>phonebook_entry</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=identifier>phonebook_entry</span><span class=special>::</span><span class=identifier>family_name</span><span class=special>>,</span> | 
|---|
| 875 |   <span class=identifier>member</span><span class=special><</span><span class=identifier>phonebook_entry</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=identifier>phonebook_entry</span><span class=special>::</span><span class=identifier>given_name</span><span class=special>></span> | 
|---|
| 876 | <span class=special>></span> <span class=identifier>ckey_t</span><span class=special>;</span> | 
|---|
| 877 |  | 
|---|
| 878 | <span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special><</span> | 
|---|
| 879 |   <span class=identifier>phonebook_entry</span><span class=special>,</span> | 
|---|
| 880 |   <span class=identifier>indexed_by</span><span class=special><</span> | 
|---|
| 881 |     <span class=identifier>ordered_non_unique</span><span class=special><</span>  | 
|---|
| 882 |       <span class=identifier>ckey_t</span><span class=special>,</span> | 
|---|
| 883 |       <span class=comment>// composite_key_result_less plays the role of | 
|---|
| 884 |       // std::less<ckey_t::result_type></span> | 
|---|
| 885 |       <span class=identifier>composite_key_result_less</span><span class=special><</span><span class=identifier>ckey_t</span><span class=special>::</span><span class=identifier>result_type</span><span class=special>></span> | 
|---|
| 886 |     <span class=special>>,</span> | 
|---|
| 887 |     <span class=identifier>ordered_unique</span><span class=special><</span> | 
|---|
| 888 |       <span class=identifier>member</span><span class=special><</span><span class=identifier>phonebook_entry</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=identifier>phonebook_entry</span><span class=special>::</span><span class=identifier>phone_number</span><span class=special>></span> | 
|---|
| 889 |     <span class=special>></span> | 
|---|
| 890 |   <span class=special>></span> | 
|---|
| 891 | <span class=special>></span> <span class=identifier>phonebook</span><span class=special>;</span> | 
|---|
| 892 | </pre></blockquote> | 
|---|
| 893 |  | 
|---|
| 894 | <h3><a name="symbol_reduction">Reduction of symbol name lengths</a></h3> | 
|---|
| 895 |  | 
|---|
| 896 | <p> | 
|---|
| 897 | The types generated on the instantiations of <code>multi_index_container</code>s | 
|---|
| 898 | typically produce very long symbol names, sometimes beyond the internal limits | 
|---|
| 899 | of some compilers. There are several techniques to shorten generated symbol | 
|---|
| 900 | names: these techniques have also the beneficial side effect that resulting error | 
|---|
| 901 | messages are more readable. | 
|---|
| 902 | </p> | 
|---|
| 903 |  | 
|---|
| 904 | <h4><a name="argument_limitation">Limitation of maximum number of arguments</a></h4> | 
|---|
| 905 |  | 
|---|
| 906 | <p> | 
|---|
| 907 | The class templates <a href="reference/indices.html#indexed_by"><code>indexed_by</code></a>, | 
|---|
| 908 | <a href="reference/indices.html#tag"><code>tag</code></a> and | 
|---|
| 909 | <a href="reference/key_extraction.html#composite_key"><code>composite_key</code></a> | 
|---|
| 910 | accept a variable number of arguments whose maximum number is limited by | 
|---|
| 911 | internal macros. Even non-used arguments contribute to the final types, | 
|---|
| 912 | so manually adjusting the corresponding macros can result in a modest reduction | 
|---|
| 913 | of symbol names. | 
|---|
| 914 | </p> | 
|---|
| 915 |  | 
|---|
| 916 | <p align="center"> | 
|---|
| 917 | <table cellspacing="0"> | 
|---|
| 918 |   <caption><b>Limiting maximum number of arguments of some class templates | 
|---|
| 919 |   of Boost.MultiIndex.</b></caption> | 
|---|
| 920 | <tr> | 
|---|
| 921 |   <th>class template</th> | 
|---|
| 922 |   <th>limiting macro</th> | 
|---|
| 923 |   <th>default value</th> | 
|---|
| 924 |   <th>default value<br>(MSVC++ 6.0)</th> | 
|---|
| 925 | </tr> | 
|---|
| 926 | <tr> | 
|---|
| 927 |   <td align="center"> <code>indexed_by</code> </td> | 
|---|
| 928 |   <td align="center"> <code>BOOST_MULTI_INDEX_LIMIT_INDEXED_BY_SIZE</code> </td> | 
|---|
| 929 |   <td align="center">20</td> | 
|---|
| 930 |   <td align="center">5</td> | 
|---|
| 931 | </tr> | 
|---|
| 932 | <tr class="odd_tr"> | 
|---|
| 933 |   <td align="center"> <code>tag</code> </td> | 
|---|
| 934 |   <td align="center"> <code>BOOST_MULTI_INDEX_LIMIT_TAG_SIZE</code> </td> | 
|---|
| 935 |   <td align="center">20</td> | 
|---|
| 936 |   <td align="center">3</td> | 
|---|
| 937 | </tr> | 
|---|
| 938 | <tr> | 
|---|
| 939 |   <td align="center"> <code>composite_key</code> </td> | 
|---|
| 940 |   <td align="center"> <code>BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE</code> </td> | 
|---|
| 941 |   <td align="center">10</td> | 
|---|
| 942 |   <td align="center">5</td> | 
|---|
| 943 | </tr> | 
|---|
| 944 | </table> | 
|---|
| 945 | </p> | 
|---|
| 946 |  | 
|---|
| 947 | <h4><a name="type_hiding">Type hiding</a></h4> | 
|---|
| 948 |  | 
|---|
| 949 | <p> | 
|---|
| 950 | Consider a typical instantiation of <code>multi_index_container</code>: | 
|---|
| 951 | </p> | 
|---|
| 952 |  | 
|---|
| 953 | <blockquote><pre> | 
|---|
| 954 | <span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special><</span> | 
|---|
| 955 |   <span class=identifier>employee</span><span class=special>,</span> | 
|---|
| 956 |   <span class=identifier>indexed_by</span><span class=special><</span> | 
|---|
| 957 |     <span class=identifier>ordered_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=identifier>employee</span><span class=special>></span> <span class=special>>,</span> | 
|---|
| 958 |     <span class=identifier>ordered_non_unique</span><span class=special><</span><span class=identifier>member</span><span class=special><</span><span class=identifier>employee</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=identifier>employee</span><span class=special>::</span><span class=identifier>name</span><span class=special>></span> <span class=special>>,</span> | 
|---|
| 959 |     <span class=identifier>ordered_unique</span><span class=special><</span><span class=identifier>member</span><span class=special><</span><span class=identifier>employee</span><span class=special>,</span><span class=keyword>int</span><span class=special>,&</span><span class=identifier>employee</span><span class=special>::</span><span class=identifier>ssnumber</span><span class=special>></span> <span class=special>></span> | 
|---|
| 960 |   <span class=special>></span> | 
|---|
| 961 | <span class=special>></span> <span class=identifier>employee_set</span><span class=special>;</span> | 
|---|
| 962 | </pre></blockquote> | 
|---|
| 963 |  | 
|---|
| 964 | <p> | 
|---|
| 965 | Then, for instance, the type <code>employee_set::nth_type<0>::type</code> | 
|---|
| 966 | resolves to the following in GCC: | 
|---|
| 967 | </p> | 
|---|
| 968 |  | 
|---|
| 969 | <blockquote><pre> | 
|---|
| 970 | <span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>detail</span><span class=special>::</span><span class=identifier>ordered_index</span><span class=special><</span> | 
|---|
| 971 |   <span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>identity</span><span class=special><</span><span class=identifier>employee</span><span class=special>>,</span> | 
|---|
| 972 |   <span class=identifier>std</span><span class=special>::</span><span class=identifier>less</span><span class=special><</span><span class=identifier>employee</span><span class=special>>,</span> | 
|---|
| 973 |   <span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>detail</span><span class=special>::</span><span class=identifier>nth_layer</span><span class=special><</span> | 
|---|
| 974 |     <span class=number>1</span><span class=special>,</span> <span class=identifier>employee</span><span class=special>,</span> | 
|---|
| 975 |     <span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>indexed_by</span><span class=special><</span> | 
|---|
| 976 |       <span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>ordered_unique</span><span class=special><</span> | 
|---|
| 977 |         <span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>identity</span><span class=special><</span><span class=identifier>employee</span><span class=special>>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span> | 
|---|
| 978 |       <span class=special>>,</span> | 
|---|
| 979 |       <span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>ordered_non_unique</span><span class=special><</span> | 
|---|
| 980 |         <span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>member</span><span class=special><</span><span class=identifier>employee</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><span class=identifier>employee</span><span class=special>::</span><span class=identifier>name</span><span class=special>>,</span> | 
|---|
| 981 |         <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span> | 
|---|
| 982 |       <span class=special>>,</span> | 
|---|
| 983 |       <span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>ordered_unique</span><span class=special><</span> | 
|---|
| 984 |         <span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>member</span><span class=special><</span><span class=identifier>employee</span><span class=special>,</span> <span class=keyword>int</span><span class=special>,</span> <span class=special>&</span><span class=identifier>employee</span><span class=special>::</span><span class=identifier>ssnumber</span><span class=special>>,</span> | 
|---|
| 985 |         <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span> | 
|---|
| 986 |       <span class=special>>,</span> | 
|---|
| 987 |       <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> | 
|---|
| 988 |       <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> | 
|---|
| 989 |       <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>,</span> <span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span> | 
|---|
| 990 |     <span class=special>>,</span> | 
|---|
| 991 |     <span class=identifier>std</span><span class=special>::</span><span class=identifier>allocator</span><span class=special><</span><span class=identifier>employee</span><span class=special>></span> | 
|---|
| 992 |   <span class=special>>,</span> | 
|---|
| 993 |   <span class=identifier>boost</span><span class=special>::</span><span class=identifier>mpl</span><span class=special>::</span><span class=identifier>vector0</span><span class=special><</span><span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>>,</span> | 
|---|
| 994 |   <span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>detail</span><span class=special>::</span><span class=identifier>ordered_unique_tag</span> | 
|---|
| 995 | <span class=special>></span> | 
|---|
| 996 | </pre></blockquote> | 
|---|
| 997 |  | 
|---|
| 998 | <p> | 
|---|
| 999 | It can be seen that a significant portion of the type name is contributed by | 
|---|
| 1000 | the <code>indexed_by<...></code> part, which is nothing but an expanded | 
|---|
| 1001 | version of the index specifier list provided in the definition of | 
|---|
| 1002 | <code>employee_set</code>. We can prevent this very long name from appearing | 
|---|
| 1003 | in the final type by encapsulating it into another, shorter-named construct: | 
|---|
| 1004 | </p> | 
|---|
| 1005 |  | 
|---|
| 1006 | <blockquote><pre> | 
|---|
| 1007 | <span class=comment>// reducing symbol names through type hiding | 
|---|
| 1008 | // type hide the index spexifier list within employee_set_indices</span> | 
|---|
| 1009 |  | 
|---|
| 1010 | <span class=keyword>struct</span> <span class=identifier>employee_set_indices</span><span class=special>:</span> | 
|---|
| 1011 |   <span class=identifier>indexed_by</span><span class=special><</span> | 
|---|
| 1012 |     <span class=identifier>ordered_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=identifier>employee</span><span class=special>></span> <span class=special>>,</span> | 
|---|
| 1013 |     <span class=identifier>ordered_non_unique</span><span class=special><</span><span class=identifier>member</span><span class=special><</span><span class=identifier>employee</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=identifier>employee</span><span class=special>::</span><span class=identifier>name</span><span class=special>></span> <span class=special>>,</span> | 
|---|
| 1014 |     <span class=identifier>ordered_unique</span><span class=special><</span><span class=identifier>member</span><span class=special><</span><span class=identifier>employee</span><span class=special>,</span><span class=keyword>int</span><span class=special>,&</span><span class=identifier>employee</span><span class=special>::</span><span class=identifier>ssnumber</span><span class=special>></span> <span class=special>></span> | 
|---|
| 1015 |   <span class=special>></span> | 
|---|
| 1016 | <span class=special>{};</span> | 
|---|
| 1017 |  | 
|---|
| 1018 | <span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special><</span> | 
|---|
| 1019 |   <span class=identifier>employee</span><span class=special>,</span> | 
|---|
| 1020 |   <span class=identifier>employee_set_indices</span> | 
|---|
| 1021 | <span class=special>></span> <span class=identifier>employee_set</span><span class=special>;</span> | 
|---|
| 1022 | </pre></blockquote> | 
|---|
| 1023 |  | 
|---|
| 1024 | <p> | 
|---|
| 1025 | <code>employee_set_indices</code> works as a conventional <code>typedef</code> | 
|---|
| 1026 | in all respects, save for a detail: its name does not explicitly | 
|---|
| 1027 | include the information contained in the <code>indexed_by</code> instantiation. | 
|---|
| 1028 | Applying this technique, <code>employee_set::nth_type<0>::type</code> | 
|---|
| 1029 | now becomes: | 
|---|
| 1030 | </p> | 
|---|
| 1031 |  | 
|---|
| 1032 | <blockquote><pre> | 
|---|
| 1033 | <span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>detail</span><span class=special>::</span><span class=identifier>ordered_index</span><span class=special><</span> | 
|---|
| 1034 |   <span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>identity</span><span class=special><</span><span class=identifier>employee</span><span class=special>>,</span> | 
|---|
| 1035 |   <span class=identifier>std</span><span class=special>::</span><span class=identifier>less</span><span class=special><</span><span class=identifier>employee</span><span class=special>>,</span> | 
|---|
| 1036 |   <span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>detail</span><span class=special>::</span><span class=identifier>nth_layer</span><span class=special><</span> | 
|---|
| 1037 |     <span class=number>1</span><span class=special>,</span> <span class=identifier>employee</span><span class=special>,</span> | 
|---|
| 1038 |     <span class=identifier>employee_set_indices</span><span class=special>,</span> | 
|---|
| 1039 |     <span class=identifier>std</span><span class=special>::</span><span class=identifier>allocator</span><span class=special><</span><span class=identifier>employee</span><span class=special>></span> | 
|---|
| 1040 |   <span class=special>>,</span> | 
|---|
| 1041 |   <span class=identifier>boost</span><span class=special>::</span><span class=identifier>mpl</span><span class=special>::</span><span class=identifier>vector0</span><span class=special><</span><span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>>,</span> | 
|---|
| 1042 |   <span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>detail</span><span class=special>::</span><span class=identifier>ordered_unique_tag</span> | 
|---|
| 1043 | <span class=special>></span> | 
|---|
| 1044 | </pre></blockquote> | 
|---|
| 1045 |  | 
|---|
| 1046 | <p> | 
|---|
| 1047 | which is considerably shorter than the original, and also more | 
|---|
| 1048 | easily parsed by a human reader. Type hiding would not work if, instead of | 
|---|
| 1049 | making <code>employee_set_indices</code> a derived <code>struct</code> of | 
|---|
| 1050 | <code>indexed_by<...></code>, we had defined it as a <code>typedef</code>: | 
|---|
| 1051 | <code>typedef</code>s are syntactic aliases and usually get expanded | 
|---|
| 1052 | by the compiler before doing any further type handling. | 
|---|
| 1053 | </p> | 
|---|
| 1054 |  | 
|---|
| 1055 | <p> | 
|---|
| 1056 | Type hiding techniques can also be applied to <code>composite_key</code> intantiations, | 
|---|
| 1057 | which often contribute a great deal to symbol name lengths. | 
|---|
| 1058 | </p> | 
|---|
| 1059 |  | 
|---|
| 1060 | <hr> | 
|---|
| 1061 |  | 
|---|
| 1062 | <div class="prev_link"><a href="reference/key_extraction.html"><img src="prev.gif" alt="key extraction" border="0"><br> | 
|---|
| 1063 | Key extraction | 
|---|
| 1064 | </a></div> | 
|---|
| 1065 | <div class="up_link"><a href="index.html"><img src="up.gif" alt="index" border="0"><br> | 
|---|
| 1066 | Index | 
|---|
| 1067 | </a></div> | 
|---|
| 1068 | <div class="next_link"><a href="performance.html"><img src="next.gif" alt="performance" border="0"><br> | 
|---|
| 1069 | Performance | 
|---|
| 1070 | </a></div><br clear="all" style="clear: all;"> | 
|---|
| 1071 |  | 
|---|
| 1072 | <br> | 
|---|
| 1073 |  | 
|---|
| 1074 | <p>Revised October 16th 2006</p> | 
|---|
| 1075 |  | 
|---|
| 1076 | <p>© Copyright 2003-2006 Joaquín M López Muñoz. | 
|---|
| 1077 | Distributed under the Boost Software  | 
|---|
| 1078 | License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt"> | 
|---|
| 1079 | LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt"> | 
|---|
| 1080 | http://www.boost.org/LICENSE_1_0.txt</a>) | 
|---|
| 1081 | </p> | 
|---|
| 1082 |  | 
|---|
| 1083 | </body> | 
|---|
| 1084 | </html> | 
|---|