const std::string::size_type cols = greeting.size() + pad * 2 + 2;
¿Por qué string::size_type
? int
se supone que funciona! ¡Tiene números!cadena :: tamaño_tipo en lugar de int
const std::string::size_type cols = greeting.size() + pad * 2 + 2;
¿Por qué string::size_type
? int
se supone que funciona! ¡Tiene números!cadena :: tamaño_tipo en lugar de int
Un corto tiene números. Como lo hace un char firmado.
Pero ninguno de esos tipos tiene la garantía de ser lo suficientemente grande como para representar los tamaños de cualquiera de las cuerdas.
string::size_type
garantiza exactamente eso. Es un tipo que es lo suficientemente grande como para representar el tamaño de una cadena, sin importar cuán grande sea esa cadena.
Para obtener un ejemplo simple de por qué es necesario, considere las plataformas de 64 bits. En general, int todavía tiene 32 bits, pero tiene más de 2^32 bytes de memoria.
Entonces, si se usó un int (firmado), no podría crear cadenas de más de 2^31 caracteres. size_type será un valor de 64 bits en esas plataformas, sin embargo, por lo que puede representar cadenas más grandes sin ningún problema.
Un typedef anidado size_type
es un requisito para los contenedores compatibles con STL (que es std::string
), por lo que el código genérico puede elegir el tipo de entero correcto para representar los tamaños.
No tiene sentido utilizarlo en el código de la aplicación, size_t
está completamente bien (int
no está, porque está firmado, y obtendrá advertencias de comparación firmadas/no firmadas).
¿Iría tan lejos como para decir que no tiene sentido? Quizás si no quieres el código más portátil, estaría bien usar 'size_t'. O para la mayoría de las situaciones prácticas de hoy puedes salirte con 'size_t'. Pero si no tuviera sentido, 'size_type' no existiría, ¿o sí? –
'size_t' * * tiene la garantía de ser lo suficientemente grande, por lo que a lo sumo" desperdicia "algo de espacio (en un registro o en la pila) por usar un valor mayor de lo necesario. Estos typedefs son para uso en código genérico, no cuando se usa 'std :: string', que es un modelo concreto. Es decir, si estás en una función de plantilla tomando un 'basic_string' arbitrario, esp. con un * allocator * arbitrario, debe usar el typedef anidado. Pero sí, no tiene sentido para 'std :: string', porque' size_t' está perfectamente bien. –
'size_t' no está firmado. Siempre que compares con 'std :: string :: npos' (en lugar de' pos> = 0'), deberías estar bien. – Jason
El ejemplo que has dado,
const std::string::size_type cols = greeting.size() + pad * 2 + 2;
es de Accelerated C++ by Koenig. También afirma la razón de su elección correcta después de esto, a saber:
El tipo std :: string define size_type a ser el nombre del tipo apropiado para la celebración de el número de caracteres de una cadena. Siempre que necesitemos una variable local para contener el tamaño de una cadena, debemos usar std :: string :: size_type como el tipo de esa variable.
La razón por la que hemos dado cols un tipo de std :: string :: size_type es para asegurar que cols es capaz de contener el número de caracteres a modo de saludo, no importa cuán grande podría ser ese número. Podríamos simplemente haber dicho que cols tiene tipo int, y de hecho, hacerlo probablemente sería . Sin embargo, el valor de cols depende del tamaño de la entrada a nuestro programa, y no tenemos control sobre cuánto tiempo puede ser esa entrada. Es concebible que alguien le de a nuestro programa una cadena tan larga que un int sea insuficiente para contener su longitud.
También es el caso en PowerPC y Cell. Y, por lo que puedo recordar, también en Alpha. Además, por supuesto, creo que x64 es la * típica * CPU de 64 bits actualmente. ;) Pero tiene razón, obviamente depende de la plataforma. – jalf
¿De qué plataforma Linux de 64 bits estamos hablando aquí? En máquinas x64, todavía tenía inyecciones de 32 bits, lo último que probé. Y en los procesadores Cell una int también es de 32 bits. Y, por extensión, estoy asumiendo lo mismo para aplicar a Linux en PowerPC.Entonces, no, el Linux ABI varía de una plataforma a otra, y la mayoría de las plataformas que conozco especifican entradas de 4 bits, incluso en Linux. – jalf
Pero tienes razón. El hardware generalmente define un ABI común que el software * debe * seguir para permitir la interoperabilidad. El SO define un ABI que generalmente es idéntico, pero podría no serlo. Y el compilador realmente implementa un ABI que de nuevo generalmente sigue al sistema operativo, pero no tiene que hacerlo en sentido estricto. – jalf