Frage
Was ist std::pair
für, warum sollte ich es verwenden, und welche Vorteile hat boost::compressed_pair
bringen?
Lösung
std::pair
ist ein Datentyp für die Gruppierung der beiden Werte zusammen als eine einzige Objekt. std::map
verwendet es für Schlüssel, Wert-Paare.
Während Sie lernen pair
, können Sie überprüfen tuple
. Es ist wie pair
aber für eine beliebige Anzahl von Werten zu gruppieren. tuple
ist ein Teil von TR1 und viele Compiler bereits enthalten sie mit ihren Standard Library-Implementierungen.
Auch Kasse Kapitel 1, "Tupeln" des Buchs Die C ++ Standard Library Erweiterungen: Eine Einführung und Referenz von Pete Becker, ISBN-13:. 9780321412997, für eine gründliche Erklärung
Andere Tipps
compressed_pair
verwendet einige Template-Tricks um Platz zu sparen. In C ++ kann ein Objekt (kleines o) hat nicht die gleiche Adresse wie ein anderes Objekt.
Also, auch wenn Sie
struct A { };
A
Größe wird nicht 0, weil dann:
A a1;
A a2;
&a1 == &a2;
halten würde, was nicht erlaubt ist.
Aber viele Compiler werden tun, was die "leere Basisklasse Optimierung" bezeichnet wird:
struct A { };
struct B { int x; };
struct C : public A { int x; };
Hier , ist es in Ordnung für B
und C
die gleiche Größe zu haben, auch wenn sizeof(A)
nicht Null sein kann.
So boost::compressed_pair
Vorteil dieser Optimierung erfolgt und wird, soweit möglich, erben von dem einen oder anderen der Typen in dem Paar, wenn es leer ist.
So ein std::pair
aussehen könnte (ich habe ein gutes Geschäft elided, ctors usw.):
template<typename FirstType, typename SecondType>
struct pair {
FirstType first;
SecondType second;
};
bedeutet, dass wenn entweder FirstType
oder SecondType
ist A
, Ihre pair<A, int>
als sizeof(int)
größer sein muss.
Aber wenn Sie compressed_pair
verwenden, wird sie generierten Code aussehen verwendet:
struct compressed_pair<A,int> : private A {
int second_;
A first() { return *this; }
int second() { return second_; }
};
Und compressed_pair<A,int>
wird nur so groß sein, wie sizeof (int).
Sie müssen manchmal zwei Werte aus einer Funktion zurückzukehren, und es ist oft übertrieben, eine Klasse nur dafür zu gehen und erstellen.
std. Paar ist praktisch, in den Fällen,
Ich denke, boost: compressed_pair Lage ist, die Mitglieder der Größe 0 optimieren entfernt. Die für schwere Vorlage Maschinen in Bibliotheken meist nützlich ist.
Wenn Sie die Typen direkt steuern zu tun, es ist irrelevant.
Es kann merkwürdig klingen, dass compressed_pair kümmert sich um ein paar Bytes zu hören. Aber es kann tatsächlich wichtig sein, wenn man bedenkt, wo compressed_pair verwendet werden kann. Zum Beispiel lassen Sie sich diesen Code betrachten:
boost::function<void(int)> f(boost::bind(&f, _1));
Es kann plötzlich einen großen Einfluss hat compressed_pair in Fällen zu verwenden, wie oben. Was passiert, wenn boost :: bind speichert den Funktionszeiger und die Platzhalterbit _1
als Mitglieder in selbst oder in einem std::pair
selbst passieren könnte? Nun, es könnte aufblasen bis sizeof(&f) + sizeof(_1)
. Unter der Annahme eines Funktionszeiger 8 Byte (nicht selten vor allem für Member-Funktionen) und der Platzhalter hat ein Byte (siehe Logan Antwort dafür, warum), dann könnten wir 9 Byte für das Objekt binden gebraucht. Wegen des Ausrichtens, könnte dies zu 12 Bytes auf einem üblichen 32-Bit-System aufblasen.
Es ist die Standardklasse für ein Wertepaar zu speichern. Es ist wieder / von einigen Standardfunktionen verwendet, wie boost::function
ermutigt seine Implementierungen ein kleines Objekt Optimierung anzuwenden. Das bedeutet, dass für kleine functors, ein kleinen Puffer direkt im boost::function
Objekt eingebettet wird den Funktors zu speichern. Für größeren functors würde der Haufen durch die Verwendung Bediener neu zu erhalten Speicher verwendet werden. Rund um Schub Version 1.34 wurde beschlossen, zu verabschieden
std::map::insert
. boost::compressed_pair
behauptet, effizienter zu sein: sehen hier
std :: pair kommt für ein paar der anderen Containerklassen in der STL in praktisch.
Zum Beispiel:
std::map<>
std::multimap<>
Beide speichern std :: Paare von Schlüsseln und Werten.
Wenn die Karte und multimap verwenden, greifen Sie oft die Elemente einen Zeiger auf ein Paar verwenden.
Weitere Informationen: boost :: compressed_pair nützlich ist, wenn einer der Typen des Paares eine leere Struktur ist. Dies wird oft in Metaprogrammierung verwendet, wenn die Typen des Paares programmatisch von anderen Typen abgeleitet werden. Am Ende dann haben Sie in der Regel irgendeine Form von „leerer Struktur“.
Ich würde std :: pair für jeden „normalen“ Gebrauch bevorzugen, wenn Sie in schwere Metaprogrammierung sind.
Es ist nichts anderes als eine Struktur mit zwei Variablen unter der Haube.
Ich mag nicht wirklich std :: pair für die Funktion kehrt mit. Der Leser des Codes würde müssen wissen, was .First ist und was .second ist.
Der Kompromiss ich manchmal verwenden, sofort ständige Verweise erstellen, um .First und .second, während die Referenzen eindeutig zu benennen.
Was ist std :: pair für, warum sollte ich es verwenden?
Es ist genauso einfach zwei Elemente Tupel. Es wurde in der ersten Version von STL in Zeiten, in denen Compiler nicht weit stützten Vorlagen und metaprogramming Techniken, die zur Implementierung anspruchsvollere Art von Tupel wie Boost.Tuple .
Es ist in vielen Situationen nützlich. std::pair
wird in Standard-assoziativen Containern verwendet. Es kann als eine einfache Form des Bereichs std::pair<iterator, iterator>
verwendet werden - so eine Annahme-Algorithmen einzelnes Objekt darstellt Bereich statt zwei separat Iteratoren definieren.
(Es ist eine sinnvolle Alternative in vielen Situationen.)
Manchmal gibt es zwei Stücke von Informationen, die Sie gerade immer um zusammen passieren, sei es als Parameter oder Rückgabewert, oder was auch immer. Natürlich könnten Sie Ihr eigenes Objekt, schreiben, aber wenn es nur zwei kleine Primitive oder ähnlich ist, manchmal ein Paar scheint ganz gut.