<p>All definitions are in namespace <code>::boost::tuples</code>, but the most common names are lifted to namespace <code>::boost</code> with using declarations. These names are: <code>tuple</code>, <code>make_tuple</code>, <code>tie</code> and <code>get</code>. Further, <code>ref</code> and <code>cref</code> are defined directly under the <code>::boost</code> namespace.
For example, the following definitions are valid tuple instantiations (<code>A</code>, <code>B</code> and <code>C</code> are some user defined classes):
This is accomplished with two helper template functions: <code>ref</code> and <code>cref</code>.
Any argument can be wrapped with these functions to get the desired type.
The mechanism does not compromise const correctness since a const object wrapped with <code>ref</code> results in a tuple element with const reference type (see the fifth code line below).
Array arguments to <code>make_tuple</code> functions are deduced to reference to const types by default; there is no need to wrap them with <code>cref</code>. For example:
Note! The member get functions are not supported with MS Visual C++ compiler.
Further, the compiler has trouble with finding the non-member get functions without an explicit namespace qualifier.
Hence, all <code>get</code> calls should be qualified as: <code>tuples::get<N>(a_tuple)</code> when writing code that shoud compile with MSVC++ 6.0.
In both cases, the conversions performed are: <code>char -> int</code>, <code>B* -> A*</code> (derived class pointer to base class pointer), <code>B -> C</code> (a user defined conversion) and <code>D -> C</code> (a user defined conversion).
Tuples reduce the operators <code>==, !=, <, >, <=</code> and <code>>=</code> to the corresponding elementary operators.
This means, that if any of these operators is defined between all elements of two tuples, then the same operator is defined between the tuples as well.
The equality operators for two tuples <code>a</code> and <code>b</code> are defined as:
<ul>
<li><code>a == b</code> iff for each <code>i</code>: <code>a<sub>i</sub> == b<sub>i</sub></code></li>
Also, the comparison operators are <i>"short-circuited"</i>: elementary comparisons start from the first elements and are performed only until the result is clear.
The idea is that a function may return a tuple, only part of which you are interested in. For example (note, that <code>ignore</code> is under the <code>tuples</code> subnamespace):
The global <code>operator<<</code> has been overloaded for <code>std::ostream</code> such that tuples are
output by recursively calling <code>operator<<</code> for each element.
</p>
<p>
Analogously, the global <code>operator>></code> has been overloaded to extract tuples from <code>std::istream</code> by recursively calling <code>operator>></code> for each element.
</p>
<p>
The default delimiter between the elements is space, and the tuple is enclosed
outputs the same tuple <code>a</code> as: <code>[1.0,2,Howdy folks!]</code>
<p>The same manipulators work with <code>operator>></code> and <code>istream</code> as well. Suppose the <code>cin</code> stream contains the following data:
Then, the call #1 may be slightly faster than #2 in the code below:
<pre><code>int i; double d;
...
f1(i,d); // #1
tie(i,d) = f2(); // #2
</code></pre>
See
[<ahref=#publ_1>1</a>,
<ahref=#publ_2>2</a>]
for more in-depth discussions about efficiency.
<h4>Effect on Compile Time</h4>
<p>
Compiling tuples can be slow due to the excessive amount of template instantiations.
Depending on the compiler and the tuple length, it may be more than 10 times slower to compile a tuple construct, compared to compiling an equivalent explicitly written class, such as the <code>hand_made_tuple</code> class above.
However, as a realistic program is likely to contain a lot of code in addition to tuple definitions, the difference is probably unnoticeable.
Compile time increases between 5 to 10 percentages were measured for programs which used tuples very frequently.
With the same test programs, memory consumption of compiling increased between 22% to 27%. See
[<ahref=#publ_1>1</a>,
<ahref=#publ_2>2</a>]
for details.
</p>
<h2><aname ="portability">Portability</a></h2>
<p>The library code is(?) standard C++ and thus the library works with a standard conforming compiler.
Below is a list of compilers and known problems with each compiler:
<tr><td>Borland 5.5</td><td>Can't use function pointers or member pointers as tuple elements</td></tr>
<tr><td>Metrowerks 6.2</td><td>Can't use <code>ref</code> and <code>cref</code> wrappers</td></tr>
<tr><td>MS Visual C++</td><td>No reference elements (<code>tie</code> still works). Can't use <code>ref</code> and <code>cref</code> wrappers</td></tr>
Gary Powell has been an indispensable helping hand. In particular, stream manipulators for tuples were his idea. Doug Gregor came up with a working version for MSVC. Thanks to Jeremy Siek, William Kempf and Jens Maurer for their help and suggestions.
The comments by Vesa Karvonen, John Max Skaller, Ed Brey, Beman Dawes, David Abrahams and Hartmut Kaiser helped to improve the
The idea for the tie mechanism came from an old usenet article by Ian McCulloch, where he proposed something similar for std::pairs.
<h2><aname ="references">References</a></h2>
<p>
<aname="publ_1"></a>[1]
Järvi J.: <i>Tuples and multiple return values in C++</i>, TUCS Technical Report No 249, 1999 (<ahref="http://www.tucs.fi/publications">http://www.tucs.fi/publications</a>).
</p>
<p>
<aname="publ_2"></a>[2]
Järvi J.: <i>ML-Style Tuple Assignment in Standard C++ - Extending the Multiple Return Value Formalism</i>, TUCS Technical Report No 267, 1999 (<ahref="http://www.tucs.fi/publications">http://www.tucs.fi/publications</a>).
</p>
<p>
[3] Järvi J.:<i>Tuple Types and Multiple Return Values</i>, C/C++ Users Journal, August 2001.
Permission to copy, use, modify, sell and distribute this software and its documentation is granted provided this copyright notice appears in all copies.
This software and its documentation is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose.