46 votes

Qu'est-ce que std :: pair?

A quoi servent std::pair , pourquoi l'utiliser, et quels sont les avantages de boost::compressed_pair ?

81voto

Logan Capaldo Points 22145

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).

35voto

jwfearn Points 8813

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.

alt text

12voto

David Pierre Points 5039

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.

11voto

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.

3voto

user17481 Points 425

C'est la classe standard pour stocker une paire de valeurs. Il est retourné / utilisé par certaines fonctions standard, comme std::map::insert .

boost::compressed_pair disent plus efficaces: voir ici

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X