Vous pourriez le faire sans en-tête:
using size_t = decltype(sizeof(int));
using size_t = decltype(sizeof 1); // The shortest is my favourite.
using size_t = decltype(sizeof "anything");
C'est parce que la norme C++ nécessite:
Le résultat de l' sizeof
et sizeof...
est une constante de type std::size_t
. [ Note: std::size_t
est défini dans la norme en-tête <cstddef>
(18.2). - la note de fin ]
En d'autres termes, la norme exige que:
static_assert(std::is_same<decltype(sizeof(int)), std::size_t>::value,
"This never fails.");
Notez également qu'il est parfaitement bien de faire ce typedef
déclaration dans le mondial et dans std
d'espace de noms, tant qu'il correspond à tous les autres typedef
des déclarations de la même définition de type-nom (une erreur du compilateur est délivrée sur la non-correspondance des déclarations).
C'est parce que:
§7.1.3.1 Une définition de type nom- ne pas introduire un nouveau type de la façon dont une déclaration de classe (9.1) ou déclaration d'enum.
§7.1.3.3 Dans un non-étendue de classe, un typedef
spécificateur peut être utilisé pour redéfinir le nom de n'importe quel type déclaré dans le champ d'application pour désigner le type à qui il fait déjà référence.
Pour les sceptiques disent que cela constitue un ajout d'un nouveau type dans l'espace de noms std
, et un tel acte est explicitement interdite par la norme, et c'est UB et c'est tous là pour ça; je dois dire que cette attitude élève à ignorer et nier meilleure compréhension des enjeux sous-jacents.
La norme des interdictions de l'ajout de nouvelles déclarations et les définitions dans l'espace de noms std
car en faisant de sorte que l'utilisateur peut faire un désordre de la bibliothèque standard et tirer sur sa jambe large. Pour les rédacteurs de normes, il était plus facile pour permettre à l'utilisateur de se spécialiser un peu de choses et l'interdiction de faire quoi que ce soit, pour faire bonne mesure, plutôt que d'interdire tous les seule chose que l'utilisateur ne doit pas faire au risque de manquer quelque chose d'important (et que la jambe). Ils l'ont fait dans le passé, lorsque exigeant qu'aucun conteneur standard doit être instancié avec un type incomplète, alors qu'en fait, certains conteneurs pourraient bien faire (voir Le Standard Bibliothécaire: les Conteneurs sont Incomplètes Types de Matthew H. Austern):
... En fin de compte, tout cela semblait trop sombres et trop mal compris; le comité de normalisation ne pense pas qu'il y avait un quelconque choix, sauf pour dire que les conteneurs STL ne sont pas censés travailler avec incomplètes types. Pour faire bonne mesure, nous avons appliqué cette interdiction pour le reste de la bibliothèque standard.
... De recul, maintenant que la technologie est mieux comprise, cette décision semble encore raison sur le fond. Oui, dans certains cas, il est possible de mettre en œuvre certaines des conteneurs standard afin qu'ils puissent être instancié avec incomplètes types - mais il est également clair que, dans d'autres cas, il serait difficile ou impossible. C'était surtout la chance que le premier test, nous avons essayé, à l'aide de std::vector
, qui est arrivé à être l'un des cas faciles.
Étant donné que la langue règles exigent std::size_t
exactement l' decltype(sizeof(int))
, faisant namespace std { using size_t = decltype(sizeof(int)); }
est une de ces choses qui ne cassent pas quoi que ce soit.
Avant C++11 il n'y avait pas decltype
, et donc aucun moyen de déclarer le type d' sizeof
suite à une simple déclaration, sans faire une bonne affaire de modèles impliqués. size_t
des alias de types différents sur différentes architectures cibles, cependant, il ne serait pas une solution élégante pour ajouter un nouveau type juste pour le résultat de l' sizeof
, et il n'existe pas de standard intégré dans les typedefs. Par conséquent, la solution la plus compacte à l'époque était de mettre size_t
type d'alias dans un en-tête spécifique et document.
En C++11, il est maintenant une façon d'écrire que l'exigence exacte de la norme comme un simple déclaration.