A quoi servent std::pair
, pourquoi l'utiliser, et quels sont les avantages de boost::compressed_pair
?
Réponses
Trop de publicités?compressed_pair
utilise certains modèles de la ruse pour économiser de l'espace. En C++, un objet (petit o) ne peut pas avoir la même adresse qu'un autre objet.
Donc, même si vous avez
struct A { };
A
's taille ne sera pas 0, car alors:
A a1;
A a2;
&a1 == &a2;
tiendrait, qui n'est pas autorisé.
Mais de nombreux compilateurs faire ce qu'on appelle le "vide de la classe de base de l'optimisation":
struct A { };
struct B { int x; };
struct C : public A { int x; };
Ici, c'est bien pour B
et C
à avoir la même taille, même si sizeof(A)
ne peut pas être zéro.
Donc, boost::compressed_pair
prend avantage de cette optimisation et, si possible, d'hériter de l'une ou l'autre des types de la paire, s'il est vide.
Ainsi, un std::pair
pourrait ressembler (je l'ai ramené une bonne affaire, ctors etc.):
template<typename FirstType, typename SecondType>
struct pair {
FirstType first;
SecondType second;
};
Cela signifie que si FirstType
ou SecondType
est A
, votre pair<A, int>
doit être plus grand que sizeof(int)
.
Mais si vous utilisez compressed_pair
, le code généré sera l'apparence semblable à:
struct compressed_pair<A,int> : private A {
int second_;
A first() { return *this; }
int second() { return second_; }
};
Et compressed_pair<A,int>
sera seulement aussi grand que sizeof(int).
std::pair
est un type de données pour le regroupement des deux valeurs ensemble, comme un seul objet. std::map
utilise pour la clé, des paires de valeurs.
Pendant que vous êtes en train d'apprendre pair
, vous pourriez découvrez tuple
. C'est comme pair
, mais pour le regroupement d'un nombre arbitraire de valeurs. tuple
fait partie de TR1 et de nombreux compilateurs déjà inclus avec leurs implémentations de la Bibliothèque Standard.
Aussi, la caisse Chapitre 1, "n-Uplets," le livre Du C++ Standard Library Extensions: Un Tutoriel et de Référence par Pete Becker, ISBN-13: 9780321412997, pour une explication détaillée.
Vous devez parfois renvoyer 2 valeurs d'une fonction, et il est souvent excessif de créer une classe rien que pour cela.
std: pair est utile dans ces cas là.
Je pense que boost: comprim_pair est capable d’optimiser les membres de taille 0. Ce qui est surtout utile pour les modèles lourds dans les bibliothèques.
Si vous contrôlez les types directement, cela n'a aucune importance.
Il peut sembler étrange d'entendre que compressed_pair se soucie de quelques octets. Mais il peut être important lorsque l'on considère où compressed_pair peut être utilisé. Par exemple, prenons ce code:
boost::function<void(int)> f(boost::bind(&f, _1));
Il peut tout d'un coup avoir un grand impact pour l'utilisation compressed_pair dans des cas comme ci-dessus. Ce qui pourrait arriver si boost::bind stocke le pointeur de fonction et de la place porte- _1
membres en elle-même ou dans un std::pair
en elle-même? Eh bien, il pourrait gonfler jusqu'à sizeof(&f) + sizeof(_1)
. En supposant un pointeur de fonction a 8 octets (pas rare, en particulier pour les fonctions de membre) et l'espace réservé a un octet (voir Logan réponse à pourquoi), alors nous pourrions avoir besoin de 9 octets pour la liaison de l'objet. En raison de l'alignement, ce qui pourrait gonfler jusqu'à 12 octets sur une habitude système 32 bits.
boost::function
encourage sa mise en oeuvre pour appliquer un petit objet de l'optimisation. Cela signifie que pour les petites foncteurs, un petit tampon directement intégré dans l' boost::function
objet est utilisé pour stocker le foncteur. Pour les plus grands foncteurs, le tas pourrait être utilisé par l'aide de l'opérateur new pour obtenir la mémoire. Autour de boost version 1.34, il a été décidé d'adopter cette optimisation, car il a été pensé que l'on pouvait gagner quelques très grands avantages de performance.
Maintenant, raisonnable (pourtant, peut-être encore assez petit) limite pour un petit tampon serait de 8 octets. C'est, à notre très simple de lier l'objet serait de ne pas tenir dans la mémoire tampon de petite taille, et aurait besoin de nouvel opérateur pour être stocké. Si la liaison de l'objet ci-dessus utilise un compressed_pair
, il peut effectivement réduire sa taille de 8 octets (soit 4 octets pour les non-membres de pointeur de fonction souvent), parce que l'espace réservé est rien de plus qu'un objet vide.
Donc, ce qui peut apparaître comme juste de gaspiller beaucoup de pensée pour seulement quelques octets peuvent avoir un impact significatif sur les performances.