Was sind gute Anwendungsfälle für Tupel in C ++ 11?
Was sind gute Anwendungsfälle für die Verwendung von Tupeln in C++11? Ich habe zum Beispiel eine Funktion, die definiert einen lokalen struct wie folgt:
template<typename T, typename CmpF, typename LessF>
void mwquicksort(T *pT, int nitem, const int M, CmpF cmp, LessF less)
{
struct SI
{
int l, r, w;
SI() {}
SI(int _l, int _r, int _w) : l(_l), r(_r), w(_w) {}
} stack[40];
//etc
War ich erwägen, zu ersetzen, die SI
struct mit einem std::tuple<int,int,int>
was eine wesentlich kürzere Erklärung mit bequemen Konstruktoren und Operatoren bereits vorgegeben, allerdings mit folgenden Nachteilen:
- Tupel-Elemente sind versteckt in dunklen, Implementierung-definiert Strukturen. Obwohl Visual studio interpretiert und zeigt Ihren Inhalt schön, ich kann immer noch nicht setzen bedingte Haltepunkte, die abhängig von dem Wert der Tupel-Elemente.
- Den Zugriff auf einzelne Tupel-Felder (
get<0>(some_tuple)
) ist weit Ausführlicher als der Zugriff auf struct-Elemente (s.l
). - Zugriff auf Felder über den Namen ist viel informativer (und kürzer!) als von numerischen index.
Die letzten beiden Punkte sind etwas angesprochen tie
Funktion. Angesichts dieser Nachteile, was wäre ein guter use-case für Tupel?
UPDATE Stellt sich heraus, dass VS2010 SP1 debugger nicht zu zeigen, den Inhalt des folgenden array std::tuple<int, int, int> stack[40]
aber es funktioniert, wenn es codiert mit einer struct. So die Entscheidung ist im Grunde ein no-brainer: wenn Sie jemals haben werden, die Prüfung der Werte verwenden Sie ein struct [esp. wichtig bei Debugger wie GDB].
InformationsquelleAutor der Frage zvrba | 2012-04-21
Du musst angemeldet sein, um einen Kommentar abzugeben.
Gut, meiner Meinung nach, der wichtigste Teil ist der generische code. Schreiben von generischem code, der funktioniert auf allen Arten von Strukturen ist viel schwieriger, als das schreiben von Generika, die Arbeit auf die Tupel. Zum Beispiel, die
std::tie
Funktion, die Sie erwähnt, Sie wäre fast unmöglich zu machen, für Strukturen.dies ermöglicht Ihnen, Dinge zu tun wie diese:
std::tie
std::tuple_cat
.Die Sache ist, es hört nicht auf mit diesen benutzt, können die Menschen erweitern diese Liste und schreiben von generischen Funktionen basiert auf Tupeln, die ist viel schwerer zu tun mit Strukturen. Wer weiß, vielleicht morgen jemand findet eine geniale Verwendung für die Serialisierung Zwecke.
InformationsquelleAutor der Antwort KillianDS
Es ist eine einfache Möglichkeit zur Rückgabe mehrerer Werte aus einer Funktion;
Die Ergebnis-Werte können verwendet werden, aus wie folgt:
InformationsquelleAutor der Antwort mirk
Ich denke, die meisten verwenden für
tuple
s kommt ausstd::tie
:Zusammen mit vielen anderen Beispiele in den Antworten hier. Ich finde dieses Beispiel, die am häufigsten jedoch nützlich, da es spart eine Menge Aufwand, wie es in C++03.
InformationsquelleAutor der Antwort LB--
Haben Sie jemals
std::pair
? Viele der Orte, die Sie möchten, verwendenstd::tuple
sind ähnlich, aber nicht beschränkt auf genau zwei Werte.Die Nachteile, die Sie der Liste für die Tupel gelten auch für std::pair, manchmal, Sie wollen eine mehr expressive Art mit besserer Namen für seine Mitglieder als
first
undsecond
aber manchmal Sie brauchen das nicht. Das gleiche gilt für Tupel.InformationsquelleAutor der Antwort Jonathan Wakely
Ich denke, es ist KEINE gute Verwendung für Tupel außerhalb von details der Implementierung der einige generische Bibliothek-Funktion.
Die (mögliche) Rettung in der Eingabe nicht kompensiert die Verluste in der selbst-Dokumentation Eigenschaften der resultierenden code.
Ersetzen von Tupeln für Strukturen, die nur nimmt Sie einen aussagekräftigen Namen für ein Feld, und ersetzen Sie das Feld name mit "Nummer" (wie das schlecht durchdachte Konzept von einem std::pair).
Zurückgeben mehrerer Werte mithilfe von Tupeln ist viel weniger selbst-dokumentieren dann die alternativen -- Rückkehr benannte Typen oder mit benannten Referenzen. Ohne diese selbst-Dokumentation, es ist leicht zu verwechseln die Reihenfolge der zurückgegebenen Werte, wenn Sie sich gegenseitig Cabrio.
InformationsquelleAutor der Antwort igorlord
Den realen Anwendungsfälle sind Situationen, in denen man namenlosen Elemente - variadic-templates und lambda-Funktionen. In beiden Situationen können Sie Unbenannte Elemente mit unbekannten Arten und somit auch der einzige Weg, Sie zu speichern ist ein struct mit Unbenannte Elemente: std::tuple. In jeder anderen situation, Sie haben einen bekannten # der name-in der Lage, Elemente mit bekannten Typen und können daher eine normale Struktur, das ist die beste Antwort, die 99% der Zeit.
Zum Beispiel, sollten Sie NICHT verwenden std::tuple "mehrere returns" von den gewöhnlichen Funktionen oder Vorlagen w/eine Feste Anzahl von generischen inputs. Verwenden Sie eine Reale Struktur. Ein reales Objekt ist WEIT mehr "generic" als die std::tuple cookie-cutter, denn Sie geben können, ein reales Objekt buchstäblich jeder Oberfläche. Es wird auch geben Ihnen viel mehr Typ-Sicherheit und Flexibilität in öffentlichen Bibliotheken.
Vergleichen Sie einfach diese 2 Klasse member-Funktionen:
Mit einem echten "geo-Koordinate" Objekt kann ich einen operator bool() gibt false zurück, wenn das übergeordnete Objekt hatte keine Position. Über seine APIs-Benutzer konnte sich der x -, y -, z-Standorte. Aber hier ist die große Sache - wenn ich beschließe, GeoCoordinate 4D, indem ein Zeit-Feld in 6 Monaten, die aktuellen Nutzer den code nicht brechen. Ich kann das nicht mit dem std::tuple version.
InformationsquelleAutor der Antwort Zack Yezek
Interoperabilität mit anderen Programmiersprachen verwenden, Tupeln und zurückgeben mehrerer Werte, ohne die Anrufer zu verstehen, alle zusätzlichen Typen. Das sind die ersten beiden die mir einfallen.
InformationsquelleAutor der Antwort John Zwinck
Kann ich nicht kommentieren, mirk Antwort, also werde ich einen separaten Antwort:
Ich denke Tupel Hinzugefügt, um die standard-wie auch für funktionale Stil der Programmierung. Als ein Beispiel, während der code wie
ist allgegenwärtig in der traditionellen C++, denn es ist die einzige Möglichkeit, mehrere Objekte von einer Funktion zurückgegeben wird, das ist ein Greuel für die funktionale Programmierung. Jetzt können Sie schreiben
So haben Sie die chance, um Nebenwirkungen zu vermeiden und Wandelbarkeit, erlauben für pipelining, und, zur gleichen Zeit, zur Erhaltung der semantischen Kraft Ihrer Funktion.
InformationsquelleAutor der Antwort julio