'size_t' vs 'contenedor :: size_type'

108

¿Hay alguna diferencia entre size_ty container::size_type?

Lo que entiendo es que size_tes más genérico y se puede usar para cualquier size_types.

¿Pero está container::size_typeoptimizado para tipos específicos de contenedores?

Charles Khunt
fuente

Respuestas:

108

Los contenedores estándar definen size_typecomo un typedef a Allocator::size_type(Asignador es un parámetro de plantilla), que para std::allocator<T>::size_typeestá típicamente define para ser size_t(o un tipo compatible). Entonces, para el caso estándar, son lo mismo.

Sin embargo, si usa un asignador personalizado, se podría usar un tipo subyacente diferente. Por eso container::size_typees preferible para la máxima generalidad.

Evan Terán
fuente
2
¿Puede aclarar esta respuesta? He revisado los proyectos de normas desde hace mucho tiempo N1804y no veo ninguna relación entre Allocator::size_typey size_type. Un vistazo rápido a libstdc ++ tampoco muestra nada similar a esto.
Shafik Yaghmour
1
@ShafikYaghmour, Esta respuesta está un poco desactualizada, pero para maximizar la portabilidad, creo que el consejo sigue siendo válido: C ++ 03 especificó "Tabla 32: size_type: un tipo que puede representar el tamaño del objeto más grande en el modelo de asignación". En ese momento, size_tfue la apuesta práctica la implementación de esas limitaciones. Sin embargo, en C ++ 11, ahora se define esencialmente como: std::make_unsigned<X::difference_type>::typepor defecto. Lo que en la práctica, probablemente será el mismo o compatible con size_t.
Evan Teran
2
CUIDADO la respuesta es incorrecta .... ver stackoverflow.com/questions/4849678/… TL: DR: los asignadores size_type deben ser size_t y en C ++ 17 size_type quedará obsoleto tal cual.
user3063349
1
@ user3063349 No veo nada en esa página, ni en el estándar C ++ 2017 (23.10.8), que insinúe la size_typedesaprobación. ¿Lo que da?
Marc.2377
42
  • size_tse define como el tipo utilizado para el tamaño de un objeto y depende de la plataforma .
  • container::size_typees el tipo que se utiliza para el número de elementos del contenedor y depende del contenedor .

Todos los stdcontenedores utilizan size_tcomo el size_type, pero cada proveedor de biblioteca independiente elige un tipo que considera apropiado para su contenedor.

Si miras , encontrará que los size_typecontenedores de Qt dependen de la versión. En Qt3 lo fue unsigned inty en Qt4 se cambió a int.

TimW
fuente
1
Me parece un poco extraño tener el tamaño de algo expresado como int. ¿Podríamos alguna vez tener un tamaño negativo para un contenedor?
Mihai Todor
10
@MihaiTodor: no es inusual que la gente use tipos firmados para todo, supongo que Qt está haciendo lo mismo. La razón es que las operaciones mixtas (en particular las comparaciones) son un área de desastre tal que muchas personas prefieren evitar el uso de tipos sin firmar para los números, que tener que lidiar con operaciones mixtas o evitarlas. El hecho de que los tipos sin signo no puedan expresar números negativos no significa que tengas que usarlos para números que no pueden ser negativos :-) Confieso que me sorprende que sea, en intlugar de ssize_t, intalgo pequeño.
Steve Jessop
2
"Todos los contenedores estándar usan size_t como size_type" muy muy falso y engañoso. Sí, generalmente lo hacen (al menos todos mis compiladores lo hicieron de esa manera) pero la referencia del lenguaje C ++ no indica que debe ser similar para todos los contenedores stl. así que cuidado
user3063349
8

Porque std::[w]string, std::[w]string::size_typees igual a std::allocator<T>::size_type, que es igual a std::size_t. Para otros contenedores, es algún tipo de entero sin signo definido por la implementación.

A veces es útil tener el tipo exacto, así que, por ejemplo, uno sabe dónde se envuelve el tipo (me gusta, a UINT_MAX) para poder hacer uso de eso. O para plantillas, donde realmente necesita pasar dos tipos idénticos a plantillas de función / clase.

A menudo encuentro que uso size_tpor brevedad o iteradores de todos modos. En código genérico, dado que generalmente no sabe con qué instancia de contenedor se usa su plantilla y qué tamaño tienen esos contenedores, tendrá que usar Container::size_typetypedef si necesita almacenar el tamaño de los contenedores.

Johannes Schaub - litb
fuente