2016-02-11 2 views
13

Warum ist std::pair<A,B> nicht dasselbe wie std::tuple<A,B>? Es war schon immer komisch, nicht einfach das eine durch das andere ersetzen zu können. Sie sind etwas konvertierbar, aber es gibt Beschränkungen.Warum ist std :: pair <A,B> nicht dasselbe wie std :: tuple <A,B>? (Gibt es wirklich keinen Weg?)

Ich weiß, dass std::pair<A,B> erforderlich ist, um die zwei Datenelemente A first und B second haben, so kann es nicht nur eine Art Alias ​​std::tuple<A,B> sein. Aber meine Intuition sagt, dass wir std::tuple<A,B> spezialisieren könnten, das ist ein Tupel mit genau zwei Elementen, um die Definition dessen, was der Standard erfordert, std::pair zu sein. Und alias dies zu std::pair.

Ich denke, das wäre nicht möglich, da es zu einfach ist, um nicht schon daran gedacht zu werden, aber es wurde nicht in g ++ 's libstdC++ zum Beispiel getan (Ich sah nicht den Quellcode von anderen Bibliotheken). Was wäre das Problem dieser Definition? Ist es "nur", dass es die Binärkompatibilität der Standardbibliothek durchbrechen würde?

+0

Möglicherweise aufgrund von Implementierungseinschränkungen (Tupel werden rekursiv implementiert, indem Sie entweder ein Unterobjekt mit kürzerem Tupeltyp verwenden oder davon erben). Jedes Tupel der Größe> = 3 würde mit den Mitgliedern dort enden. –

+0

@Revolver_Ocelot Hmm guter Punkt ... Aber was ist mit einigen rekursiven 'tuple_impl' (wie das aktuelle Tupel implementiert ist), dann alias' tuple = tuple_impl' für 0, 1 und> = 3 Elemente, aber 'tuple = pair_impl 'für 2 Elemente sowie' Paar = Tupel '. Ich hoffe du verstehst das. Grundsätzlich eine weitere Alias-Indirektion, die rekursive Implementierungsdetails versteckt. – leemes

+3

@Revolver_Ocelot Moderne 'Tupel'-Implementierungen sind nicht rekursiv. – Columbo

Antwort

3

Sie müssen auf Dinge wie SFINAE und Überladung achten. Zum Beispiel wird der Code unten noch wohlgeformt, aber sie würde es illegal machen:

void f(std::pair<int, int>); 
void f(std::tuple<int, int>); 

Derzeit ich zwischen Paar und Tupel durch Überladungsauflösung, SFINAE, Template-Spezialisierung, etc. Diese Instrumente würden alle werden Mehrdeutigkeiten können unfähig, sie auseinander zu halten, wenn du ihnen das gleiche machst. Dies würde bestehenden Code brechen.

Möglicherweise gab es eine Gelegenheit, es als Teil von C++ 11 einzuführen, aber es gibt jetzt sicherlich nicht.

+0

Diese Antwort ist am einfachsten zu verstehen - Sie erklären, wie die Kompatibilität würde gebrochen werden, wenn wir es * jetzt * geändert haben. Ich denke, es wäre möglich gewesen, ein Tupel in C++ 11 einzuführen, das paarweise kompatibel war, wenn es zwei Elemente hatte (im Sinne dessen, wie ich es beschrieben habe). – leemes

0

Ich habe das nicht versucht und habe nicht die Bandbreite, um dies zu tun. Sie könnten versuchen, eine Spezialisierung von std :: tuple zu machen, die von einem sd :: -Paar abgeleitet ist. Jemand sagt mir bitte, das wird nicht funktionieren oder ist eine besonders schreckliche Idee. Ich vermute, dass Sie mit Accessoren Probleme bekommen würden.

+0

Sie dürfen nur 'std ::' Vorlagen für Ihre eigenen Klassen spezialisieren, nicht generell. – MSalters

+0

Wenn ich meine eigenen Klassen spezialisieren kann, kann ich Standardklassen spezialisieren. Ich folge deiner Argumentation nicht. TBH Ich bin mir nicht sicher, dass es furchtbar wichtig ist, also werde ich nicht verärgert sein, wenn du nicht antwortest. – Nicole

+0

Es ist ausdrücklich durch den Standard verboten. Es gibt keine Argumentation. (Es gibt eine Begründung; es würde die Implementierung der Standardbibliothek komplizieren, wenn Sie könnten). – MSalters

2

Dies ist rein historisch. std::pair existieren seit C++ 98, Tupel kam danach und war ursprünglich nicht Teil des Standards.

Abwärtskompatibilität ist die größte Belastung für die C++ - Evolution und verhindert, dass einige nette Dinge einfach erledigt werden können!

Verwandte Themen