Le tuple est l'association de plusieurs éléments, structurellement semblable à un struct. On peut par exemple y stocker une relation élément/attribut (
{objet : "Ballon", nombre: 4}), une position (
{abscisse : 349, ordonne : 89, profondeur : 2}) ...
Ainsi ils peuvent contenir plusieurs sorte de données, et cette association forme un type, là ou un tableau ne peut en contenir qu'un, et ne précise pas leur nombre. De plus, par rapport à une structure anonyme utilisé en plusieurs endroits, un tuple sera toujours compatible avec d'autres tuples de même caractéristique, puisqu'il s'agit d'un type unique.
Utiliser les tuples
Vous n'avez pas besoin de librairie à lier, mais vous devez inclure les en-têtes suivants :
Code : C++ | #include <boost/tuple/tuple.hpp> // Base
#include <boost/tuple/tuple_comparison.hpp> // Opérateurs de comparaison
#include <boost/tuple/tuple_io.hpp> // Tuples et IO
|
Pour créer un tuple, vous devez spécifier les types de ses éléments, puis éventuellement les initialiser :
Code : C++ | boost::tuple<int, int, double> monTuple(1,2,3.14);
|
Cependant, cette notation est pénible en cela qu'elle oblige à écrire chaque type. Pour pallier ce problème, Boost met à notre disposition une fonction permettant de créer des tuples.
Code : C++ | monTuple = make_tuple(1, 2, 3, 4);
|
Si le tuple que vous essayez de créer doit contenir une référence, il faut le spécifier, autrement l'élément pointé sera copié :
ref()
pour forcer une référence,
cref()
pour forcer une référence constante.
Si vous utilisez ref()
, comme dans le 5éme exemple, sur une référence constante, l'attribut const
ne sera pas perdu.
Code : C++ | MaClasse1 a; MaClasse2 b; const MaClasse1 ca = a;
make_tuple(cref(a), b); // Résultat : tuple<const MaClasse1&, MaClasse2>
make_tuple(ref(a), b); // Résultat : tuple<MaClasse1&, MaClasse2>
make_tuple(ref(a), cref(b)); // Résultat : tuple<MaClasse1&, const MaClasse2&>
make_tuple(cref(ca)); // Résultat : tuple<const MaClasse1&>
make_tuple(ref(ca)); // Résultat : tuple<const MaClasse1&>
|
Vous pouvez accéder au contenu du tuple de deux manières :
- Via la fonction boost::get<NumeroElement>(tuple);
- Via la méthode tuple.get<NumeroElement>();
Ce qui donne par exemple :
Code : C++ | tuple <int, int> t(1,2);
get<0>(t) = 10; // t vaut 10|2
std::cout << t.get<1>(); // Le programme affiche 2
|
Notez d'ailleurs que vous n'aurez pas de mauvaise surprise : les accès à des données inexistantes (par exemple,
t.get<3>()
pour un tuple à 2 valeurs) sont détectés à la compilation, grâce à l'utilisation de template.
les indices commencent comme d'habitude à zéro et non pas à un
Comparaisons
Les tuples ont des opérateurs de comparaison (
==
,
>
,
<
, ...) : le premier élément du tuple A sera comparé au premier élément du tuple B, le second au second, et ainsi de suite. Les tuples sont égaux si tous les éléments les constituants sont égaux un à un.
Flux
Vous pouvez imprimer un tuple sous la forme (1 2 3 Orly) en utilisant l'opérateur << :
Code : C++ | tuple<int,int,int,std::string> t(1,2,3,std::string("Orly"));
std::cout << t;
|
Pour obtenir un tuple depuis l'entrée standard, faites de même :
Code : C++
L'entrée devra être formatée comme la sortie (exemple : "(1 2 3 Aaa)")
Si vous le souhaitez, vous pouvez changer les délimiteurs, tant pour la sortie que pour l'entrée :
- set_open(char) défini le caractère de début.
- set_close(char) défini le caractère de fin.
- set_delimiter(char) défini le délimiteur
Le code suivant aura pour sortie
[1,2,3,Aaa]
Code : C++ | std::cout << tuples::set_open('[') << tuples::set_close(']') << tuples::set_delimiter(',') << t;
|
Avec le compilateur MS Visual C++, il est possible que, malgré la conformance aux standards du code des tuples, les références ne puissent être utilisés dans les tuples (les fonctions ref() et cref() ne fonctionnant pas.)