blob: ce80c4d2166d59c457d40435f82c45ea4f86e3ca [file] [log] [blame]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0.1 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Boost.MultiIndex Documentation - Compiler specifics</title>
<link rel="stylesheet" href="style.css" type="text/css">
<link rel="start" href="index.html">
<link rel="prev" href="reference/key_extraction.html">
<link rel="up" href="index.html">
<link rel="next" href="performance.html">
</head>
<body>
<h1><img src="../../../boost.png" alt="boost.png (6897 bytes)" align=
"middle" width="277" height="86">Boost.MultiIndex Compiler specifics</h1>
<div class="prev_link"><a href="reference/key_extraction.html"><img src="prev.gif" alt="key extraction" border="0"><br>
Key extraction
</a></div>
<div class="up_link"><a href="index.html"><img src="up.gif" alt="index" border="0"><br>
Index
</a></div>
<div class="next_link"><a href="performance.html"><img src="next.gif" alt="performance" border="0"><br>
Performance
</a></div><br clear="all" style="clear: all;">
<hr>
<p>
Boost.MultiIndex has been tried in different compilers, with
various degrees of success. We list the limitations encountered,
along with suitable workarounds when available.
</p>
<h2>Contents</h2>
<ul>
<li><a href="#bcb_64">Borland C++ Builder 6.4 and later</a></li>
<li><a href="#comeau_43101_win_vc7_71">Comeau C/C++ 4.3.10.1 for Windows (VC++ 9.0 backend)</a></li>
<li><a href="#compaq_65">Compaq C++ 6.5-042 and later for Tru64 UNIX</a></li>
<li>
<a href="#gcc_32">GNU GCC 3.2 and later</a>
<ul>
<li><a href="#gcc_tru64">GNU GCC for Tru64 UNIX</a></li>
<li><a href="#gcc_4_darwin">Darwin GCC 4.0</a></li>
</ul>
</li>
<li><a href="#acc_612_ia64">HP aC++ A.06.12 and later for HP-UX IA64</a></li>
<li><a href="#acc_380_pa_risc">HP aC++ A.03.80 for HP-UX PA-RISC</a></li>
<li><a href="#va_60">IBM VisualAge C++ V6.0 for AIX</a></li>
<li><a href="#xl_90">IBM XL C/C++ V9.0 for AIX and later</a></li>
<li><a href="#intel_81_lin">Intel C++ Compiler for Linux 8.1 and later</a></li>
<li><a href="#intel_91_mac">Intel C++ Compiler for Mac OS 9.1 and later</a></li>
<li><a href="#intel_80_win">Intel C++ Compiler for Windows 32-bit 8.0 and later</a></li>
<li><a href="#intel_100_win64">Intel C++ Compiler for Windows 64-bit 10.0 and later</a></li>
<li><a href="#cw_83">Metrowerks CodeWarrior 8.3</a></li>
<li><a href="#cw_9x">Metrowerks CodeWarrior 9 and later</a></li>
<li>
<a href="#msvc_60">Microsoft Visual C++ 6.0 Service Pack 5</a>
<ul>
<li><a href="#msvc_60_stlport_453">Microsoft Visual C++ 6.0 Service Pack 5 + STLport 4.5.3 and later</a></li>
</ul>
</li>
<li>
<a href="#msvc_70">Microsoft Visual C++ 7.0</a>
<ul>
<li><a href="#msvc_70_stlport_501">Microsoft Visual C++ 7.0 + STLport 5.0.1</a></li>
</ul>
</li>
<li><a href="#msvc_71">Microsoft Visual C++ 7.1</a></li>
<li><a href="#msvc_80">Microsoft Visual C++ 8.0 and later</a></li>
<li><a href="#sun_10">Sun Studio 10 and later for Solaris</a></li>
<li><a href="#portability">Portability techniques</a>
<ul>
<li><a href="#member_offset">Use of <code>member_offset</code></a></li>
<li><a href="#mem_fun_explicit">Use of <code>const_mem_fun_explicit</code> and
<code>mem_fun_explicit</code></a></li>
<li><a href="#composite_key_no_pts"><code>composite_key</code> in compilers
without partial template specialization</a></li>
<li><a href="#symbol_reduction">Reduction of symbol name lengths</a>
<ul>
<li><a href="#argument_limitation">Limitation of maximum number of arguments</a></li>
<li><a href="#type_hiding">Type hiding</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h2><a name="bcb_64">Borland C++ Builder 6.4 and later</a></h2>
<p>
Currently, Boost.MultiIndex cannot be used with any of BCB 6.4 up to BCB 2006
and CodeGear C++Builder 2010.
The number of problems encountered during the tests makes it unlikely that
future versions of the library can be made to work under these compilers.
</p>
<h2><a name="comeau_43101_win_vc7_71">Comeau C/C++ 4.3.10.1 for Windows (VC++ 9.0 backend)</a></h2>
<p>
<b>Note:</b> Last tested in Boost 1.38. The information might be no longer accurate.
</p>
<p>
No problems have been detected with this compiler. The library fails to compile,
however, when Microsoft Visual C++ 6.0 is used as the backend. Last time they were
tested (Boost.1.34.1), VC++ 7.0/7.1 backends worked correctly. The beta 2 version of
the Comeau compiler 4.3.10.1 has been used.
</p>
<h2><a name="compaq_65">Compaq C++ 6.5-042 and later for Tru64 UNIX</a></h2>
<p>
<b>Note:</b> Last tested in Boost 1.38. The information might be no longer accurate.
</p>
<p>
No problems have been detected with this compiler. Last tested for version 7.1-006.
</p>
<h2><a name="gcc_32">GNU GCC 3.2 and later</a></h2>
<p>
No problems have been detected with several versions of this compiler
starting from 3.2. The following versions have been explicitly tested:
<ul>
<li>GCC 3.4.3 under Linux x86-64,</li>
<li>GCC 4.0.1 (Apple Computer, Inc. build 5370), (Apple Inc. build 5490), (Apple Inc. build 5493) under Mac OS,</li>
<li>GCC 4.1.2 20080704 (Red Hat 4.1.2-44) under Linux x86-64,</li>
<li>GCC 4.2.1 20070719 [FreeBSD] under FreeBSD,</li>
<li>GCC 4.2.4 under Linux x86-64,</li>
<li>GCC 4.3.2 under Linux x86-64,</li>
<li>GCC 4.3.3 under Linux x86-64,</li>
<li>GCC 4.3.3 gnu++0x under Linux x86-64,</li>
<li>GCC 4.3.4 under Linux x86-64,</li>
<li>GCC 4.4.1 under Linux, Linux x86-64 and MinGW,</li>
<li>GCC 4.4.1 gnu++0x under Linux x86-64 and MinGW.</li>
</ul>
Boost.MultiIndex does not work with versions 3.1 and prior of GCC.
</p>
<h3><a name="gcc_tru64">GNU GCC for Tru64 UNIX</a></h3>
<p>
On this platform, GCC is not able to handle debug symbol names whose length
exceeds 32,768 bytes, resulting in the error <code>mips-tfile, ... string
too big</code>. You may encounter this issue with heavily templatized
code like Boost.MultiIndex, which typically produces long symbol names. The problem
can be overcome by omitting the compiler option <code>-g</code> (generate debugging
information.) Alternatively, consult the section on
<a href="#symbol_reduction">reduction of symbol name lengths</a> for various
applicable workarounds.
</p>
<h3><a name="gcc_4_darwin">Darwin GCC 4.0</a></h3>
<p>
Build 4061 of GCC 4.0, shipped with Darwin 8.2 and prior (Mac OS X 10.4.2 and
prior), corresponds to a prerelease version of GNU GCC 4.0.0 which introduces
a <a href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17435">regression bug</a>
related to binding of references to temporary objects. This bug precludes the
usage of Boost.MultiIndex
<a href="tutorial/debug.html#invariant_check">invariant-checking mode</a>; other
than this, Boost.MultiIndex works correctly.
The bug is corrected in GCC 4.0 Apple build 5026, which is in sync with the official
release of GNU GCC 4.0.0, so the invariant-checking mode is available from this
upgrade.
</p>
<h2><a name="acc_612_ia64">HP aC++ A.06.12 and later for HP-UX IA64</a></h2>
<p>
<b>Note:</b> Last tested in Boost 1.38. The information might be no longer accurate.
</p>
<p>
No problems have been detected with this compiler.
Last tested for version A.06.17.
</p>
<h2><a name="acc_380_pa_risc">HP aC++ A.03.80 for HP-UX PA-RISC</a></h2>
<p>
<b>Note:</b> Last tested in Boost 1.38. The information might be no longer accurate.
</p>
<p>
No problems have been detected with this compiler.
Last tested for version A.03.85.
</p>
<h2><a name="va_60">IBM VisualAge C++ V6.0 for AIX</a></h2>
<p>
<b>Note:</b> Last tested in Boost 1.33.1. The information might be no longer accurate.
</p>
<blockquote><hr></blockquote>
<p>
<a href="reference/key_extraction.html#member"><code>member</code></a> not supported,
refer to the section on
<a href="#member_offset">use of <code>member_offset</code></a> for workarounds.
<code>member_offset</code> causes the compiler to emit warnings about the
use of <code>offsetof</code> with non-POD types: these warnings can be suppressed
by setting the compiler option <code>-qsuppress=1540-1281</code>, or, alternatively,
by inserting the following preprocessor directive:
</p>
<blockquote><pre>
<span class=preprocessor>#pragma</span> <span class=identifier>info</span><span class=special>(</span><span class=identifier>nolan</span><span class=special>)</span>
</pre></blockquote>
<p>
This latter pragma, however, may also eliminate other warnings not related
to the use of <code>offsetof</code>.
</p>
<blockquote><hr></blockquote>
<p>
Serialization capabilities are not available as Boost.Serialization is not
supported on this platform.
</p>
<h2><a name="xl_90">IBM XL C/C++ V9.0 for AIX and later</a></h2>
<p>
<a href="reference/key_extraction.html#member"><code>member</code></a> not supported,
refer to the section on
<a href="#member_offset">use of <code>member_offset</code></a> for workarounds.
<code>member_offset</code> causes the compiler to emit warnings about the
use of <code>offsetof</code> with non-POD types: these warnings can be suppressed
by setting the compiler option <code>-qsuppress=1540-1281</code>, or, alternatively,
by inserting the following preprocessor directive:
</p>
<blockquote><pre>
<span class=preprocessor>#pragma</span> <span class=identifier>info</span><span class=special>(</span><span class=identifier>nolan</span><span class=special>)</span>
</pre></blockquote>
<p>
This latter pragma, however, may also eliminate other warnings not related
to the use of <code>offsetof</code>.
Other than this, Boost.MultiIndex works without problems.
Last tested for version V10.1.
</p>
<h2><a name="intel_81_lin">Intel C++ Compiler for Linux 8.1 and later</a></h2>
<p>
No problems have been detected with this compiler.
Last tested for compiler versions 10.0 to 11.1.
</p>
<h2><a name="intel_91_mac">Intel C++ Compiler for Mac OS 9.1 and later</a></h2>
<p>
No problems have been detected with this compiler.
Tested from version 10.1 to 11.0.
</p>
<h2><a name="intel_80_win">Intel C++ Compiler for Windows 32-bit 8.0 and later</a></h2>
<p>
When used on top of MSVC++ 7.0 or prior, argument dependent lookup is
disabled by default. This will cause problems with many Boost libraries,
and in particular with the serialization part of Boost.MultiIndex.
Argument dependent lookup is enabled by adding
<code>/Qoption,c,--arg_dep_lookup</code> to the project options.
Other than this, Boost.MultiIndex works without problems.
Last tested for compiler version 11.1.
</p>
<h2><a name="intel_100_win64">Intel C++ Compiler for Windows 64-bit 10.0 and later</a></h2>
<p>
No problems have been detected with this compiler.
Last tested for compiler version 11.1.
</p>
<h2><a name="cw_83">Metrowerks CodeWarrior 8.3</a></h2>
<p>
<b>Note:</b> Last tested in Boost 1.36. The information might be no longer accurate.
</p>
<p>
Predefined key extractors instantiated on a given type do not accept
objects of derived types. For instance:
</p>
<blockquote><pre>
<span class=keyword>struct</span> <span class=identifier>base</span><span class=special>{};</span>
<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>
<span class=special>...</span>
<span class=identifier>identity</span><span class=special>&lt;</span><span class=identifier>base</span><span class=special>&gt;</span> <span class=identifier>key_extractor</span><span class=special>;</span>
<span class=identifier>derived</span> <span class=identifier>x</span><span class=special>;</span>
<span class=comment>// not accepted by this compiler: an explicit cast to base is required</span>
<span class=identifier>key_extractor</span><span class=special>(</span><span class=identifier>x</span><span class=special>);</span>
</pre></blockquote>
<p>
Other than this, Boost.MultiIndex works without problems under Mac OS and Windows (last
tested under Windows only).
</p>
<h2><a name="cw_9x">Metrowerks CodeWarrior 9 and later</a></h2>
<p>
<b>Note:</b> Last tested in Boost 1.34.1. The information might be no longer accurate.
</p>
<p>
Boost.MultiIndex works correctly with versions of this compiler from 9.0 to
9.5, both under Mac OS and Windows.
</p>
<h2><a name="msvc_60">Microsoft Visual C++ 6.0 Service Pack 5</a></h2>
<p>
<b>Note:</b> Last tested in Boost 1.36. The information might be no longer accurate.
</p>
<blockquote><hr></blockquote>
<p>
Beginning with Boost.1.36, Boost.Serialization is no longer supported in this
compiler, thus the serialization capabilities cannot be used.
</p>
<blockquote><hr></blockquote>
<p>
<a href="reference/key_extraction.html#member"><code>member</code></a> not supported,
refer to the section on
<a href="#member_offset">use of <code>member_offset</code></a> for workarounds.
</p>
<p>
<a href="reference/key_extraction.html#const_mem_fun"><code>const_mem_fun</code></a> and
<a href="reference/key_extraction.html#mem_fun"><code>mem_fun</code></a>
not supported, refer to the section on
<a href="#mem_fun_explicit">use of <code>const_mem_fun_explicit</code> and
<code>mem_fun_explicit</code></a> for workarounds.
</p>
<blockquote><hr></blockquote>
<p>
No support for <a href="reference/multi_index_container.html#index_retrieval">index retrieval</a>
and <a href="reference/multi_index_container.html#projection">projection</a>
nested types and member functions:
<ul>
<li><code>nth_index</code>,</li>
<li><code>index</code>,</li>
<li><code>nth_index_iterator</code>,</li>
<li><code>nth_index_const_iterator</code>,</li>
<li><code>index_iterator</code>,</li>
<li><code>index_const_iterator</code>,</li>
<li><code>get</code>,</li>
<li><code>project</code>.</li>
</ul>
You can use instead their global equivalents. Also, this compiler does not
implement argument dependent lookup, so you might need to explicitly qualify
these global names with <code>::boost::multi_index</code>.
</p>
<blockquote><hr></blockquote>
<p>
<code>boost::multi_index::multi_index_container</code> is imported to
<code>namespace boost</code> by means of a <code>using</code> declaration.
MSVC++ 6.0, however, does not properly handle this import. So, instead of
writing:
</p>
<blockquote><pre>
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index_container</span><span class=special>&lt;...&gt;</span>
</pre></blockquote>
<p>
use the following:
</p>
<blockquote><pre>
<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>&lt;...&gt;</span>
</pre></blockquote>
<p>
or else resort to a directive <code>using namespace boost::multi_index</code>.
</p>
<blockquote><hr></blockquote>
<p>
The lack of partial template specialization support in MSVC++ 6.0
results in some inconveniences when using <code>composite_key</code> that
can be remedied as explained in
<a href="#composite_key_no_pts">"<code>composite_key</code>
in compilers without partial template specialization"</a>.
</p>
<blockquote><hr></blockquote>
<p>
Due to problems with function template ordering support,
<a href="reference/key_extraction.html#composite_key_compare"><code>composite_key_compare</code></a>
and related classes do not accept the notational variations of
<code>operator()</code> where one of the operands is treated as if
included into a tuple of length 1. As a result, the user cannot ever
omit tuple enclosing when specifying the arguments of lookup operations
involving composite keys.
</p>
<blockquote><hr></blockquote>
<p>
Predefined key extractors instantiated on a given type do not accept
objects of derived types. For instance:
</p>
<blockquote><pre>
<span class=keyword>struct</span> <span class=identifier>base</span><span class=special>{};</span>
<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>
<span class=special>...</span>
<span class=identifier>identity</span><span class=special>&lt;</span><span class=identifier>base</span><span class=special>&gt;</span> <span class=identifier>key_extractor</span><span class=special>;</span>
<span class=identifier>derived</span> <span class=identifier>x</span><span class=special>;</span>
<span class=comment>// not accepted by this compiler: an explicit cast to base is required</span>
<span class=identifier>key_extractor</span><span class=special>(</span><span class=identifier>x</span><span class=special>);</span>
</pre></blockquote>
<blockquote><hr></blockquote>
<p>
MSVC++ 6.0 presents serious limitations for the maximum length of
symbol names generated by the compiler, which might result in the
linker error
<code><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/html/lnk1179.asp">LNK1179</a>:
invalid or corrupt file: duplicate comdat
comdat</code>. To overcome this problem, consult the section on
<a href="#symbol_reduction">reduction of symbol name lengths</a> for various
applicable workarounds.
</p>
<blockquote><hr></blockquote>
<p>
Under some circumstances, the compiler emits the error
<a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/html/C2587.asp">
<code>C2587</code></a><code>: '_U' : illegal use of local variable as
default parameter</code>, inside the MSVC internal header
<code>&lt;xlocnum></code>.
This problem is a recurrent bug of the compiler, and has been reported in
other unrelated libraries, like the
<a href="../../../libs/graph/doc/table_of_contents.html">Boost Graph Library</a>,
<a href="../../../libs/multi_array/doc/index.html">Boost.MultiArray</a>,
<a href="../../../libs/regex/index.html">Boost.Regex</a>,
<a href="http://www.cgal.org/">CGAL</a> and
<a href="http://www.mysql.com/downloads/api-mysql++.html">MySQL++</a>.
The error is triggered, though not in a systematic manner, by the use
of <code>multi_index_container</code> iterator constructor. Two workarounds exist:
the first consists of avoiding this constructor and replacing
code like:
</p>
<blockquote><pre>
<span class=identifier>multi_index_container</span><span class=special>&lt;...&gt;</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>
</pre></blockquote>
<p>
with equivalent operations:
</p>
<blockquote><pre>
<span class=identifier>multi_index_container</span><span class=special>&lt;...&gt;</span> <span class=identifier>s</span><span class=special>;</span>
<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>
</pre></blockquote>
<p>
The second workaround has not been confirmed by the author, but it is given
on the Internet in connection with this error appearing in other libraries.
Replace line 84 of <code>&lt;xlocnum&gt;</code>
<blockquote><pre>
<span class=preprocessor>#define</span> <span class=identifier>_VIRTUAL</span> <span class=keyword>virtual</span>
</pre></blockquote>
<p>
with the following:
</p>
<blockquote><pre>
<span class=preprocessor>#define</span> <span class=identifier>_VIRTUAL</span>
</pre></blockquote>
<p>
<b>Warning</b>: it is not known whether this
replacement can result in unexpected side effects in code implicitly
using <code>&lt;xlocnum></code>.
</p>
<blockquote><hr></blockquote>
<p>
In general, the extensive use of templates by Boost.MultiIndex puts this compiler
under severe stress, so that several internal limitations may be reached.
The following measures can help alleviate these problems:
<ul>
<li>Set the compiler option <code>/Zm</code> (Specify Memory Allocation Limit)
to increase the amount of memory available for compilation. Usual values for
this option range from 300 to 800.</li>
<li>If in debug mode, try switching from <code>/ZI</code> (Program Database for
Edit and Continue) to a less demanding type of debugging information
(<code>/Zi</code>, <code>/Z7</code> or <code>/Zd</code>.)</li>
<li>Play with the precompiled headers options. Usually, turning this feature
off yields the best results.</li>
<li>If the compiler emits the error
<a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/html/c1055.asp">
<code>C1055</code></a><code>: compiler limit : out of keys</code>, try
disabling the option <code>/Gm</code> (Enable Minimal Rebuild.) In these
cases, it is also beneficial to split the project into smaller
subprojects.</li>
</ul>
</p>
<h3>
<a name="msvc_60_stlport_453">Microsoft Visual C++ 6.0 Service Pack 5
+ STLport 4.5.3 and later</a>
</h3>
<p>
<b>Note:</b> Last tested in Boost 1.36. The information might be no longer accurate.
</p>
<p>
Boost.MultiIndex works for this configuration. The same limitations apply as
in MSVC++ 6.0 with its original Dinkumware standard library. STLport 4.6.2 and
5.0.1 has also been confirmed to work correctly.
</p>
<h2><a name="msvc_70">Microsoft Visual C++ 7.0</a></h2>
<p>
<b>Note:</b> Last tested in Boost 1.35. The information might be no longer accurate.
</p>
<blockquote><hr></blockquote>
<p>
Beginning with Boost.1.36, Boost.Serialization is no longer supported in this
compiler, thus the serialization capabilities cannot be used.
</p>
<blockquote><hr></blockquote>
<p>
<a href="reference/key_extraction.html#member"><code>member</code></a> not supported,
refer to the section on
<a href="#member_offset">use of <code>member_offset</code></a> for workarounds.
</p>
<blockquote><hr></blockquote>
<p>
No support for <a href="reference/multi_index_container.html#index_retrieval">index retrieval</a>
and <a href="reference/multi_index_container.html#projection">projection</a>
nested types and member functions:
<ul>
<li><code>nth_index</code>,</li>
<li><code>index</code>,</li>
<li><code>nth_index_iterator</code>,</li>
<li><code>nth_index_const_iterator</code>,</li>
<li><code>index_iterator</code>,</li>
<li><code>index_const_iterator</code>,</li>
<li><code>get</code>,</li>
<li><code>project</code>.</li>
</ul>
You can use instead their global equivalents. Also, this compiler does not
implement argument dependent lookup, so you might need to explicitly qualify
these global names with <code>::boost::multi_index</code>.
</p>
<blockquote><hr></blockquote>
<p>
<code>boost::multi_index::multi_index_container</code> is imported to
<code>namespace boost</code> by means of a <code>using</code> declaration.
MSVC++ 7.0, however, does not properly handle this import. So, instead of
writing:
</p>
<blockquote><pre>
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index_container</span><span class=special>&lt;...&gt;</span>
</pre></blockquote>
<p>
use the following:
</p>
<blockquote><pre>
<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>&lt;...&gt;</span>
</pre></blockquote>
<p>
or else resort to a directive <code>using namespace boost::multi_index</code>.
</p>
<blockquote><hr></blockquote>
<p>
The lack of partial template specialization support in MSVC++ 7.0
results in some inconveniences when using <code>composite_key</code> that
can be remedied as explained in
<a href="#composite_key_no_pts">"<code>composite_key</code>
in compilers without partial template specialization"</a>.
</p>
<blockquote><hr></blockquote>
<p>
Due to problems with function template ordering support,
<a href="reference/key_extraction.html#composite_key_compare"><code>composite_key_compare</code></a>
and related classes do not accept the notational variations of
<code>operator()</code> where one of the operands is treated as if
included into a tuple of length 1. As a result, the user cannot ever
omit tuple enclosing when specifying the arguments of lookup operations
involving composite keys.
</p>
<blockquote><hr></blockquote>
<p>
Predefined key extractors instantiated on a given type do not accept
objects of derived types. For instance:
</p>
<blockquote><pre>
<span class=keyword>struct</span> <span class=identifier>base</span><span class=special>{};</span>
<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>
<span class=special>...</span>
<span class=identifier>identity</span><span class=special>&lt;</span><span class=identifier>base</span><span class=special>&gt;</span> <span class=identifier>key_extractor</span><span class=special>;</span>
<span class=identifier>derived</span> <span class=identifier>x</span><span class=special>;</span>
<span class=comment>// not accepted by this compiler: an explicit cast to base is required</span>
<span class=identifier>key_extractor</span><span class=special>(</span><span class=identifier>x</span><span class=special>);</span>
</pre></blockquote>
<h3><a name="msvc_70_stlport_501">Microsoft Visual C++ 7.0 + STLport 5.0.1</a></h3>
<p>
<b>Note:</b> Last tested in Boost 1.35. The information might be no longer accurate.
</p>
<p>
Boost.MultiIndex works for this configuration. The same issues apply as in
MSVC++ 7.0 with its original Dinkumware standard library.
</p>
<h2><a name="msvc_71">Microsoft Visual C++ 7.1</a></h2>
<p>
Problems have been reported when compiling the library with the <code>/Gm</code>
option (Enable Minimal Rebuild.) Seemingly, this is due to an
internal defect of the compiler (see for instance
<a href="http://lists.boost.org/boost-users/2004/02/5987.php">
this mention of a similar issue</a> in the Boost Users mailing list.)
If <code>/Gm</code> is turned off, Boost.MultiIndex compiles and runs
without further problems.
</p>
<h2><a name="msvc_80">Microsoft Visual C++ 8.0 and later</a></h2>
<p>
No problems have been detected with this compiler, both in 32-bit and 64-bit modes.
Last tested for compiler versions 8.0 to 10.0.
</p>
<h2><a name="sun_10">Sun Studio 10 and later for Solaris</a></h2>
<p>
No problems have been detected with this platform. Last tested for compiler version
Sun C++ 5.10 (Sun Studio 12 Update 1).
The option <code>-library=stlport4</code> was used to replace the default
standard library with STLport.
</p>
<h2><a name="portability">Portability techniques</a></h2>
<h3><a name="member_offset">Use of <code>member_offset</code></a></h3>
<p>
The <code>member</code> key extractor poses some problems in compilers
that do not properly support pointers to members as non-type
template arguments, as indicated by the
<a href="../../../libs/config/config.htm">Boost Configuration Library</a>
defect macro <code>BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS</code>.
The following compilers have been confirmed not
to work correctly with <code>member</code>:
<ul>
<li>MSVC++ 6.0/7.0,</li>
<li>Intel C++ 7.0/7.1 for Windows,</li>
<li>VisualAge 6.0/9.0 for AIX.</li>
</ul>
This program can help determine if your compiler
properly supports pointers to members as non-type template parameters:
</p>
<blockquote><pre>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>iostream</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <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=identifier>y</span><span class=special>;</span>
<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>
<span class=special>};</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>int</span> <span class=identifier>pair</span><span class=special>::*</span> <span class=identifier>PtrToPairMember</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>foo</span>
<span class=special>{</span>
<span class=keyword>int</span> <span class=identifier>bar</span><span class=special>(</span><span class=identifier>pair</span><span class=special>&amp;</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>
<span class=special>};</span>
<span class=keyword>int</span> <span class=identifier>main</span><span class=special>()</span>
<span class=special>{</span>
<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>
<span class=identifier>foo</span><span class=special>&lt;&amp;</span><span class=identifier>pair</span><span class=special>::</span><span class=identifier>x</span><span class=special>&gt;</span> <span class=identifier>fx</span><span class=special>;</span>
<span class=identifier>foo</span><span class=special>&lt;&amp;</span><span class=identifier>pair</span><span class=special>::</span><span class=identifier>y</span><span class=special>&gt;</span> <span class=identifier>fy</span><span class=special>;</span>
<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>&lt;&lt;</span><span class=string>&quot;KO&quot;</span><span class=special>&lt;&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>endl</span><span class=special>;</span>
<span class=keyword>else</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>cout</span><span class=special>&lt;&lt;</span><span class=string>&quot;OK&quot;</span><span class=special>&lt;&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>endl</span><span class=special>;</span>
<span class=keyword>return</span> <span class=number>0</span><span class=special>;</span>
<span class=special>}</span>
</pre></blockquote>
<p>
If you find a compiler that does not pass the test, and for which
<code>BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS</code> is <i>not</i> defined,
please report to the Boost developers mailing list.
</p>
<p>To overcome this defect, a replacement utility
<a href="reference/key_extraction.html#member_offset"><code>member_offset</code></a>
has been provided that does the work of <code>member</code> at the
expense of less convenient notation and the possibility of
non-conformance with the standard. Please consult
the reference for further information on <code>member_offset</code>.
As an example of use, given the class
</p>
<blockquote><pre>
<span class=keyword>class</span> <span class=identifier>A</span>
<span class=special>{</span>
<span class=keyword>int</span> <span class=identifier>x</span><span class=special>;</span>
<span class=special>}</span>
</pre></blockquote>
<p>
the instantiation <code>member&lt;A,int,&amp;A::x></code> can be simulated then
as <code>member_offset&lt;A,int,offsetof(A,x)></code>.
</p>
<p>
For those writing portable code, Boost.MultiIndex provides the ternary macro
<a href="reference/key_extraction.html#boost_multi_index_member"><code>BOOST_MULTI_INDEX_MEMBER</code></a>.
Continuing with the example above, the
expression
</p>
<blockquote><pre>
<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>
</pre></blockquote>
<p>
expands by default to
</p>
<blockquote><pre>
<span class=identifier>member</span><span class=special>&lt;</span><span class=identifier>A</span><span class=special>,</span><span class=keyword>int</span><span class=special>,&amp;</span><span class=identifier>A</span><span class=special>::</span><span class=identifier>x</span><span class=special>&gt;</span>
</pre></blockquote>
<p>
or alternatively to
</p>
<blockquote><pre>
<span class=identifier>member_offset</span><span class=special>&lt;</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>)&gt;</span>
</pre></blockquote>
<p>
if <code>BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS</code> is defined.
</p>
<h3><a name="mem_fun_explicit">Use of <code>const_mem_fun_explicit</code> and
<code>mem_fun_explicit</code></a></h3>
<p>
MSVC++ 6.0 has problems with <code>const</code> member functions as non-type
template parameters, and thus does not accept the <code>const_mem_fun</code>
key extractor. A simple workaround, fortunately, has been found, consisting
in specifying the <i>type</i> of these pointers as an additional template
parameter. The alternative
<a href="reference/key_extraction.html#const_mem_fun_explicit"><code>const_mem_fun_explicit</code></a>
extractor adopts this solution; for instance, given the type
</p>
<blockquote><pre>
<span class=keyword>struct</span> <span class=identifier>A</span>
<span class=special>{</span>
<span class=keyword>int</span> <span class=identifier>f</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<span class=special>};</span>
</pre></blockquote>
<p>
the extractor <code>const_mem_fun&lt;A,int,&amp;A::f></code> can be replaced by
<code>const_mem_fun_explicit&lt;A,int,int (A::*)()const,&amp;A::f></code>. A similar
<code>mem_fun_explicit</code> class template is provided for non-constant
member functions.
</p>
<p>
If you are writing cross-platform code, the selection of either key extractor
is transparently handled by the macro
<a href="reference/key_extraction.html#boost_multi_index_const_mem_fun"><code>BOOST_MULTI_INDEX_CONST_MEM_FUN</code></a>,
so that
</p>
<blockquote><pre>
<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>
</pre></blockquote>
<p>
expands by default to
</p>
<blockquote><pre>
<span class=identifier>const_mem_fun</span><span class=special>&lt;</span><span class=identifier>A</span><span class=special>,</span><span class=keyword>int</span><span class=special>,&amp;</span><span class=identifier>A</span><span class=special>::</span><span class=identifier>f</span><span class=special>&gt;</span>
</pre></blockquote>
<p>
but resolves to
</p>
<blockquote><pre>
<span class=identifier>const_mem_fun_explicit</span><span class=special>&lt;</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>,&amp;</span><span class=identifier>A</span><span class=special>::</span><span class=identifier>f</span><span class=special>&gt;</span>
</pre></blockquote>
<p>
in MSVC++ 6.0. Non-<code>const</code> member functions are covered by
<a href="reference/key_extraction.html#mem_fun_explicit"><code>mem_fun_explicit</code></a>
and the macro
<a href="reference/key_extraction.html#boost_multi_index_mem_fun"><code>BOOST_MULTI_INDEX_MEM_FUN</code></a>.
</p>
<h3><a name="composite_key_no_pts"><code>composite_key</code> in compilers
without partial template specialization</a></h3>
<p>
When using <code>composite_key</code>s, lookup is performed by passing
tuples of values: this ability is achieved by suitably specializing
the class templates <code>std::equal_to</code>, <code>std::less</code>,
<code>std::greater</code> and <code>boost::hash</code> for
<a href="reference/key_extraction.html#composite_key_result">
<code>composite_key_result</code></a> instantiations so that they
provide the appropriate overloads accepting tuples --and in the case
of <code>std::less</code> and <code>std::greater</code>, also partial
tuples where only the first components are specified.
</p>
<p>
In those compilers that do not support partial template specialization,
these specializations cannot be provided, and so
tuple-based lookup is not available by default. In this case,
<code>multi_index_container</code> instantiations using composite keys
will work as expected, both for ordered and hashed indices,
except that lookup operations will not accept tuples as an argument.
For ordered indices, the most obvious workaround
to this deficiency involves explicitly specifying the comparison
predicate with
<a href="reference/key_extraction.html#composite_key_compare"><code>composite_key_compare</code></a>;
in the case of hashed indices we can use the analogous
<a href="reference/key_extraction.html#composite_key_equal_to"><code>composite_key_equal_to</code></a>
and
<a href="reference/key_extraction.html#composite_key_hash"><code>composite_key_hash</code></a>.
This substitution is tedious as the elementary components for all the constituent key extractors must
be explicitly typed. For this reason, Boost.MultiIndex provides the following replacement
class templates
<ul>
<li><a href="reference/key_extraction.html#composite_key_result_equal_to">
<code>composite_key_result_equal_to</code></a>,</li>
<li><a href="reference/key_extraction.html#composite_key_result_less">
<code>composite_key_result_less</code></a>,</li>
<li><a href="reference/key_extraction.html#composite_key_result_greater">
<code>composite_key_result_greater</code></a> and</li>
<li><a href="reference/key_extraction.html#composite_key_result_hash">
<code>composite_key_result_hash</code></a>,</li>
</ul>
that act as the missing specializations of <code>std::equal_to</code>, <code>std::less</code>,
<code>std::greater</code> and <code>boost::hash</code> for <code>composite_key_result</code>s.
They can be used as follows:
</p>
<blockquote><pre>
<span class=keyword>typedef</span> <span class=identifier>composite_key</span><span class=special>&lt;</span>
<span class=identifier>phonebook_entry</span><span class=special>,</span>
<span class=identifier>member</span><span class=special>&lt;</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>,&amp;</span><span class=identifier>phonebook_entry</span><span class=special>::</span><span class=identifier>family_name</span><span class=special>&gt;,</span>
<span class=identifier>member</span><span class=special>&lt;</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>,&amp;</span><span class=identifier>phonebook_entry</span><span class=special>::</span><span class=identifier>given_name</span><span class=special>&gt;</span>
<span class=special>&gt;</span> <span class=identifier>ckey_t</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=identifier>phonebook_entry</span><span class=special>,</span>
<span class=identifier>indexed_by</span><span class=special>&lt;</span>
<span class=identifier>ordered_non_unique</span><span class=special>&lt;</span>
<span class=identifier>ckey_t</span><span class=special>,</span>
<span class=comment>// composite_key_result_less plays the role of
// std::less&lt;ckey_t::result_type&gt;</span>
<span class=identifier>composite_key_result_less</span><span class=special>&lt;</span><span class=identifier>ckey_t</span><span class=special>::</span><span class=identifier>result_type</span><span class=special>&gt;</span>
<span class=special>&gt;,</span>
<span class=identifier>ordered_unique</span><span class=special>&lt;</span>
<span class=identifier>member</span><span class=special>&lt;</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>,&amp;</span><span class=identifier>phonebook_entry</span><span class=special>::</span><span class=identifier>phone_number</span><span class=special>&gt;</span>
<span class=special>&gt;</span>
<span class=special>&gt;</span>
<span class=special>&gt;</span> <span class=identifier>phonebook</span><span class=special>;</span>
</pre></blockquote>
<h3><a name="symbol_reduction">Reduction of symbol name lengths</a></h3>
<p>
The types generated on the instantiations of <code>multi_index_container</code>s
typically produce very long symbol names, sometimes beyond the internal limits
of some compilers. There are several techniques to shorten generated symbol
names: these techniques have also the beneficial side effect that resulting error
messages are more readable.
</p>
<h4><a name="argument_limitation">Limitation of maximum number of arguments</a></h4>
<p>
The class templates <a href="reference/indices.html#indexed_by"><code>indexed_by</code></a>,
<a href="reference/indices.html#tag"><code>tag</code></a> and
<a href="reference/key_extraction.html#composite_key"><code>composite_key</code></a>
accept a variable number of arguments whose maximum number is limited by
internal macros. Even non-used arguments contribute to the final types,
so manually adjusting the corresponding macros can result in a modest reduction
of symbol names.
</p>
<p align="center">
<table cellspacing="0">
<caption><b>Limiting maximum number of arguments of some class templates
of Boost.MultiIndex.</b></caption>
<tr>
<th>class template</th>
<th>limiting macro</th>
<th>default value</th>
<th>default value<br>(MSVC++ 6.0)</th>
</tr>
<tr>
<td align="center">&nbsp;<code>indexed_by</code>&nbsp;</td>
<td align="center">&nbsp;<code>BOOST_MULTI_INDEX_LIMIT_INDEXED_BY_SIZE</code>&nbsp;</td>
<td align="center">20</td>
<td align="center">5</td>
</tr>
<tr class="odd_tr">
<td align="center">&nbsp;<code>tag</code>&nbsp;</td>
<td align="center">&nbsp;<code>BOOST_MULTI_INDEX_LIMIT_TAG_SIZE</code>&nbsp;</td>
<td align="center">20</td>
<td align="center">3</td>
</tr>
<tr>
<td align="center">&nbsp;<code>composite_key</code>&nbsp;</td>
<td align="center">&nbsp;<code>BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE</code>&nbsp;</td>
<td align="center">10</td>
<td align="center">5</td>
</tr>
</table>
</p>
<h4><a name="type_hiding">Type hiding</a></h4>
<p>
Consider a typical instantiation of <code>multi_index_container</code>:
</p>
<blockquote><pre>
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=identifier>employee</span><span class=special>,</span>
<span class=identifier>indexed_by</span><span class=special>&lt;</span>
<span class=identifier>ordered_unique</span><span class=special>&lt;</span><span class=identifier>identity</span><span class=special>&lt;</span><span class=identifier>employee</span><span class=special>&gt;</span> <span class=special>&gt;,</span>
<span class=identifier>ordered_non_unique</span><span class=special>&lt;</span><span class=identifier>member</span><span class=special>&lt;</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>,&amp;</span><span class=identifier>employee</span><span class=special>::</span><span class=identifier>name</span><span class=special>&gt;</span> <span class=special>&gt;,</span>
<span class=identifier>ordered_unique</span><span class=special>&lt;</span><span class=identifier>member</span><span class=special>&lt;</span><span class=identifier>employee</span><span class=special>,</span><span class=keyword>int</span><span class=special>,&amp;</span><span class=identifier>employee</span><span class=special>::</span><span class=identifier>ssnumber</span><span class=special>&gt;</span> <span class=special>&gt;</span>
<span class=special>&gt;</span>
<span class=special>&gt;</span> <span class=identifier>employee_set</span><span class=special>;</span>
</pre></blockquote>
<p>
Then, for instance, the type <code>employee_set::nth_index&lt;0&gt;::type</code>
resolves to the following in GCC:
</p>
<blockquote><pre>
<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>&lt;</span>
<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>&lt;</span><span class=identifier>employee</span><span class=special>&gt;,</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>less</span><span class=special>&lt;</span><span class=identifier>employee</span><span class=special>&gt;,</span>
<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>&lt;</span>
<span class=number>1</span><span class=special>,</span> <span class=identifier>employee</span><span class=special>,</span>
<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>&lt;</span>
<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>&lt;</span>
<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>&lt;</span><span class=identifier>employee</span><span class=special>&gt;,</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>&gt;,</span>
<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>&lt;</span>
<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>&lt;</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>&amp;</span><span class=identifier>employee</span><span class=special>::</span><span class=identifier>name</span><span class=special>&gt;,</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>&gt;,</span>
<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>&lt;</span>
<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>&lt;</span><span class=identifier>employee</span><span class=special>,</span> <span class=keyword>int</span><span class=special>,</span> <span class=special>&amp;</span><span class=identifier>employee</span><span class=special>::</span><span class=identifier>ssnumber</span><span class=special>&gt;,</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>&gt;,</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> <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> <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>&gt;,</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>allocator</span><span class=special>&lt;</span><span class=identifier>employee</span><span class=special>&gt;</span>
<span class=special>&gt;,</span>
<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>&lt;</span><span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>&gt;,</span>
<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>
<span class=special>&gt;</span>
</pre></blockquote>
<p>
It can be seen that a significant portion of the type name is contributed by
the <code>indexed_by&lt;...&gt;</code> part, which is nothing but an expanded
version of the index specifier list provided in the definition of
<code>employee_set</code>. We can prevent this very long name from appearing
in the final type by encapsulating it into another, shorter-named construct:
</p>
<blockquote><pre>
<span class=comment>// reducing symbol names through type hiding
// type hide the index spexifier list within employee_set_indices</span>
<span class=keyword>struct</span> <span class=identifier>employee_set_indices</span><span class=special>:</span>
<span class=identifier>indexed_by</span><span class=special>&lt;</span>
<span class=identifier>ordered_unique</span><span class=special>&lt;</span><span class=identifier>identity</span><span class=special>&lt;</span><span class=identifier>employee</span><span class=special>&gt;</span> <span class=special>&gt;,</span>
<span class=identifier>ordered_non_unique</span><span class=special>&lt;</span><span class=identifier>member</span><span class=special>&lt;</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>,&amp;</span><span class=identifier>employee</span><span class=special>::</span><span class=identifier>name</span><span class=special>&gt;</span> <span class=special>&gt;,</span>
<span class=identifier>ordered_unique</span><span class=special>&lt;</span><span class=identifier>member</span><span class=special>&lt;</span><span class=identifier>employee</span><span class=special>,</span><span class=keyword>int</span><span class=special>,&amp;</span><span class=identifier>employee</span><span class=special>::</span><span class=identifier>ssnumber</span><span class=special>&gt;</span> <span class=special>&gt;</span>
<span class=special>&gt;</span>
<span class=special>{};</span>
<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span>
<span class=identifier>employee</span><span class=special>,</span>
<span class=identifier>employee_set_indices</span>
<span class=special>&gt;</span> <span class=identifier>employee_set</span><span class=special>;</span>
</pre></blockquote>
<p>
<code>employee_set_indices</code> works as a conventional <code>typedef</code>
in all respects, save for a detail: its name does not explicitly
include the information contained in the <code>indexed_by</code> instantiation.
Applying this technique, <code>employee_set::nth_index&lt;0&gt;::type</code>
now becomes:
</p>
<blockquote><pre>
<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>&lt;</span>
<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>&lt;</span><span class=identifier>employee</span><span class=special>&gt;,</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>less</span><span class=special>&lt;</span><span class=identifier>employee</span><span class=special>&gt;,</span>
<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>&lt;</span>
<span class=number>1</span><span class=special>,</span> <span class=identifier>employee</span><span class=special>,</span>
<span class=identifier>employee_set_indices</span><span class=special>,</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>allocator</span><span class=special>&lt;</span><span class=identifier>employee</span><span class=special>&gt;</span>
<span class=special>&gt;,</span>
<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>&lt;</span><span class=identifier>mpl_</span><span class=special>::</span><span class=identifier>na</span><span class=special>&gt;,</span>
<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>
<span class=special>&gt;</span>
</pre></blockquote>
<p>
which is considerably shorter than the original, and also more
easily parsed by a human reader. Type hiding would not work if, instead of
making <code>employee_set_indices</code> a derived <code>struct</code> of
<code>indexed_by&lt;...&gt;</code>, we had defined it as a <code>typedef</code>:
<code>typedef</code>s are syntactic aliases and usually get expanded
by the compiler before doing any further type handling.
</p>
<p>
Type hiding techniques can also be applied to <code>composite_key</code> intantiations,
which often contribute a great deal to symbol name lengths.
</p>
<hr>
<div class="prev_link"><a href="reference/key_extraction.html"><img src="prev.gif" alt="key extraction" border="0"><br>
Key extraction
</a></div>
<div class="up_link"><a href="index.html"><img src="up.gif" alt="index" border="0"><br>
Index
</a></div>
<div class="next_link"><a href="performance.html"><img src="next.gif" alt="performance" border="0"><br>
Performance
</a></div><br clear="all" style="clear: all;">
<br>
<p>Revised October 14th 2009</p>
<p>&copy; Copyright 2003-2009 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</body>
</html>