Según cppreference.com size_t se define en varios encabezados, a saber
<cstddef>
<cstdio>
<cstring>
<ctime>
Y, desde C ++ 11, también en
<cstdlib>
<cwchar>
En primer lugar, me pregunto por qué es así. ¿No está esto en contradicción con el principio DRY ? Sin embargo, mi pregunta es:
¿Cuál de los encabezados anteriores debo incluir para usar size_t? ¿Importa en absoluto?

<cstddef>parastd::size_tstd::size_ty el OP no abogaba por el uso de funciones C heredadas, solo observando la cita sobre ellos compartiendo el typedef. Dudo que alguien que lea este hilo sea engañado al usar tipos / funciones heredados debido a esto, pero si quieres estar seguro de que no lo hacen, ¡entonces es justo!Respuestas:
Suponiendo que quisiera minimizar las funciones y los tipos que estaba importando, iría con,
cstddefya que no declara ninguna función y solo declara 6 tipos. Los demás se centran en dominios particulares (cadenas, tiempo, IO) que pueden no importarle.Tenga en cuenta que
cstddefsolo garantiza definirstd::size_t, es decir, definirsize_ten el espacio de nombresstd, aunque puede proporcionar este nombre también en el espacio de nombres global (efectivamente, sin formatosize_t).Por el contrario,
stddef.h(que también es un encabezado disponible en C) garantiza definirsize_ten el espacio de nombres global, y también puede proporcionarstd::size_t.fuente
size_tdecstddefes igual y siempre será igual que los demás? Parece que debería haber un archivo de encabezado común con definiciones comunes comosize_t...cstddef.<cstddef>, o todos podrían incluir algún encabezado interno que solo definasize_t.csttddefrespuesta es un error tipográfico? ¿Quizáscstddefse refiere?De hecho, la sinopsis (incluida en el estándar C ++) de varios encabezados se incluye específicamente
size_t, así como otros encabezados definen el tiposize_t(según el estándar C, ya que los<cX>encabezados son solo<X.h>encabezados ISO C con cambios notados dondesize_tno se indica la eliminación de ).Sin embargo, el estándar C ++ se refiere a
<cstddef>la definición destd::size_tPor lo tanto, y debido al hecho de que
<cstddef>solo introduce tipos y no funciones, me quedaría con este encabezado para que estéstd::size_tdisponible.Tenga en cuenta algunas cosas:
El tipo de
std::size_tse puede obtenerdecltypesin incluir un encabezadoSi planea introducir un typedef en su código de todos modos (es decir, porque escribe un contenedor y desea proporcionar un
size_typetypedef), puede usar los operadores globalsizeof,sizeof...oralignofpara definir su tipo sin incluir ningún encabezado, ya que esos operadores regresanstd::size_tpor definición estándar y puede usardecltypeen ellos:std::size_tno es per se globalmente visible, aunque las funciones constd::size_targumentos sí lo son.Las funciones de asignación y desasignación globales declaradas implícitamente
NO introduzca
size_t,stdostd::size_tyEl usuario no puede redefinir,
std::size_taunque es posible tener múltiples typedefs que se refieran al mismo tipo en el mismo espacio de nombres.Aunque, la ocurrencia de múltiples definiciones de
size_tinsidestdes perfectamente válida según 7.1.3 / 3 , no se permite agregar ninguna declaraciónnamespace stdsegún 17.6.4.2.1 / 1 :Agregar un typedef apropiado para
size_tel espacio de nombres no viola 7.1.3 pero viola 17.6.4.2.1 y conduce a un comportamiento indefinido.Aclaración: Trate de no malinterpretar 7.1.3 y no agregue declaraciones o definiciones
std(excepto en algunos casos de especialización de plantilla donde un typedef no es una especialización de plantilla). Extendiendo elnamespace stdfuente
stdno sea válido porque las typedefs duplicadas son ilegales. Declaro que es ilegal porque simplemente no puede agregar definicionesnamespace std, sin importar si serían legales.Todos los archivos de encabezado de biblioteca estándar tienen la misma definición; no importa cuál incluya en su propio código. En mi computadora, tengo la siguiente declaración en formato
_stddef.h. Este archivo está incluido en todos los archivos que enumeró.fuente
size_ten primer lugar?size_t. Puede definirlo de manera más portátil comousing size_t = decltype( sizeof( 42 ) ). Pero no es necesario, ya que<stddef.h>tiene un costo casi nulo.Podrías prescindir de un encabezado:
Esto se debe a que el estándar C ++ requiere:
En otras palabras, el estándar requiere:
También tenga en cuenta que está perfectamente bien hacer esta
typedefdeclaración en elstdespacio global y en el espacio de nombres, siempre que coincida con todas las demástypedefdeclaraciones del mismo typedef-name (se emite un error del compilador en declaraciones que no coinciden).Esto es porque:
§7.1.3.1 Un typedef-name no introduce un nuevo tipo como lo hace una declaración de clase (9.1) o una declaración de enumeración.
§7.1.3.3 En un ámbito que no sea de clase dado,
typedefse puede usar un especificador para redefinir el nombre de cualquier tipo declarado en ese ámbito para hacer referencia al tipo al que ya se refiere.A los escépticos que dicen que esto constituye una adición de un nuevo tipo en el espacio de nombres
std, y tal acto está explícitamente prohibido por el estándar, y esto es UB y eso es todo; Debo decir que esta actitud equivale a ignorar y negar una comprensión más profunda de los problemas subyacentes.El estándar prohíbe agregar nuevas declaraciones y definiciones en el espacio de nombres
stdporque al hacerlo el usuario puede hacer un lío de la biblioteca estándar y dispararse. Para los escritores estándar, era más fácil dejar que el usuario se especializara en algunas cosas específicas y prohibir hacer cualquier otra cosa por si acaso, en lugar de prohibir todo lo que el usuario no debería hacer y arriesgarse a perderse algo importante (y esa pierna). Lo hicieron en el pasado cuando requerían que ningún contenedor estándar se instanciara con un tipo incompleto, mientras que, de hecho, algunos contenedores podrían funcionar bien (ver The Standard Librarian: Containers of Incomplete Types por Matthew H. Austern ):Dado que las reglas del lenguaje requieren
std::size_tser exactasdecltype(sizeof(int)), hacernamespace std { using size_t = decltype(sizeof(int)); }es una de esas cosas que no rompen nada.Antes de C ++ 11 no
decltypehabía forma de declarar el tipo desizeofresultado en una declaración simple y, por lo tanto, no existía una buena cantidad de plantillas.size_talias diferentes tipos en diferentes arquitecturas de destino, sin embargo, no sería una solución elegante agregar un nuevo tipo integrado solo por el resultado desizeof, y no hay typedefs estándar integrados. Por lo tanto, la solución más portátil en ese momento era poner unsize_talias de tipo en algún encabezado específico y documentarlo.En C ++ 11 ahora hay una forma de escribir ese requisito exacto del estándar como una simple declaración.
fuente
size_t!" Un minuto más tarde, Mary dijo: "¡Dios mío! ¡Hay 7 definiciones desize_tencabezados de biblioteca estándar y un encabezado de proyecto que Tom está editando! ¡Probablemente hay más en las bibliotecas de terceros!" xkcd.com/927size_t, esto no responde a la pregunta real del OP: es como si le pidiera el encabezado dondeFILEse declara y usted sugeriría escribir uno propio.