Sie könnten auf einen Header verzichten:
using size_t = decltype(sizeof(int));
using size_t = decltype(sizeof 1); // The shortest is my favourite.
using size_t = decltype(sizeof "anything");
Dies liegt daran, dass der C ++ - Standard Folgendes erfordert:
Das Ergebnis von sizeof
und sizeof...
ist eine Konstante vom Typ std::size_t
. [Hinweis: std::size_t
ist im Standardheader <cstddef>
(18.2) definiert. - Endnote]
Mit anderen Worten, der Standard verlangt:
static_assert(std::is_same<decltype(sizeof(int)), std::size_t>::value,
"This never fails.");
Beachten Sie auch, dass es vollkommen in Ordnung ist, diese typedef
Deklaration im globalen und im std
Namespace abzugeben , solange sie mit allen anderen typedef
Deklarationen desselben Typedef-Namens übereinstimmt (bei nicht übereinstimmenden Deklarationen wird ein Compilerfehler ausgegeben).
Das ist weil:
§7.1.3.1 Ein typedef-Name führt keinen neuen Typ ein, wie es eine Klassendeklaration (9.1) oder eine Enum-Deklaration tut.
§7.1.3.3 In einem bestimmten Nichtklassenbereich typedef
kann ein Bezeichner verwendet werden, um den Namen eines in diesem Bereich deklarierten Typs neu zu definieren, um auf den Typ zu verweisen, auf den er sich bereits bezieht.
Für Skeptiker, die sagen, dass dies eine Hinzufügung eines neuen Typs zum Namespace darstellt std
und eine solche Handlung durch den Standard ausdrücklich verboten ist, und dies ist UB und das ist alles da; Ich muss sagen, dass diese Haltung bedeutet, ein tieferes Verständnis der zugrunde liegenden Probleme zu ignorieren und zu leugnen.
Der Standard verbietet das Hinzufügen neuer Deklarationen und Definitionen zum Namespace, std
da der Benutzer auf diese Weise die Standardbibliothek durcheinander bringen und sein gesamtes Bein abschießen kann. Für die Standardautoren war es einfacher, den Benutzer auf einige bestimmte Dinge spezialisieren zu lassen und alles andere aus gutem Grund zu verbieten, als alles zu verbieten, was der Benutzer nicht tun sollte, und das Risiko einzugehen, etwas Wichtiges (und dieses Bein) zu verpassen. Sie haben dies in der Vergangenheit getan, als sie forderten, dass kein Standardcontainer mit einem unvollständigen Typ instanziiert werden soll, während dies tatsächlich einige Container tun könnten (siehe Der Standardbibliothekar: Container unvollständiger Typen von Matthew H. Austern ):
... Am Ende schien alles zu trüb und zu schlecht verstanden; Das Standardisierungskomitee glaubte nicht, dass es eine andere Wahl gab, als zu sagen, dass STL-Container nicht mit unvollständigen Typen arbeiten sollten. Aus gutem Grund haben wir dieses Verbot auch auf den Rest der Standardbibliothek angewendet.
... Rückblickend scheint diese Entscheidung, nachdem die Technologie besser verstanden wurde, im Grunde immer noch richtig zu sein. Ja, in einigen Fällen ist es möglich, einige der Standardcontainer so zu implementieren, dass sie mit unvollständigen Typen instanziiert werden können - aber es ist auch klar, dass dies in anderen Fällen schwierig oder unmöglich wäre. Es war größtenteils Zufall, dass der erste Test, den wir versuchten, std::vector
einer der einfachen Fälle war.
Angesichts der Tatsache, dass die Sprachregeln std::size_t
genau sein müssen decltype(sizeof(int))
, ist das Tun namespace std { using size_t = decltype(sizeof(int)); }
eines der Dinge, die nichts kaputt machen.
Vor C ++ 11 gab es keine decltype
und daher keine Möglichkeit, die Art des sizeof
Ergebnisses in einer einfachen Anweisung zu deklarieren, ohne dass viele Vorlagen beteiligt waren. size_t
Aliase für verschiedene Typen auf verschiedenen Zielarchitekturen. Es wäre jedoch keine elegante Lösung, einen neuen integrierten Typ nur für das Ergebnis von hinzuzufügen sizeof
, und es gibt keine standardmäßigen integrierten Typedefs. Daher bestand die portabelste Lösung zu dieser Zeit darin, size_t
Typalias in einen bestimmten Header einzufügen und diesen zu dokumentieren.
In C ++ 11 gibt es jetzt eine Möglichkeit, die genaue Anforderung des Standards als eine einfache Deklaration aufzuschreiben.