2012-10-08 56 views
7

Para medir la posición/desplazamientos/tamaño de las secuencias, el estándar especifica std::streampos, std::streamoff y std::streamsize, pero están definidos por la implementación.std :: streampos, std :: streamoff y std :: streamsize a long long int?

¿Cómo convertir estos tipos a long long int de una manera segura y portátil? (por ejemplo, para medir un tamaño de archivo e insertarlo en una función que tome un int largo largo como argumento)

Respuesta

5

Bueno, en lo que se refiere a C++ 98/03, no eslong long int. Entonces asumiré que estás preguntando sobre C++ 11.

El streamsize y streamoff están obligados a ser typedefs de un tipo entero (streampos no es un entero, por lo que no le pasa eso a cualquier cosa que toma un long long). Como los tipos integrales son tipos básicos, solo pueden definirse mediante C++ o como una definición específica del compilador.

Por lo tanto, la única pregunta es esta: ¿estos typedefs son más grandes que long long? Todos los tipos integrales son convertibles a un tipo más grande o de igual tamaño (a pesar de firmar/firmar, pero todos los tipos aquí están firmados, así que no hay problema). Pero si es más grande ... ¿qué vas a hacer al respecto?

Suponiendo que no se puede cambiar la firma de la función que está "inyectando" en (porque si se pudiera, no hay razón para no tomar sólo streamsize como el tipo de parámetro y así evitar el problema), usted don' t tiene alguna opción. Tiene un valor de datos que es más grande que lo que necesita la función. No hay forma de evitarlo aquí.

Puede realizar una static_cast en un long long para cerrar el compilador, pero esto no ayudará si el tamaño real no cabe en un long long.

En última instancia, este es un problema difícil de resolver. Usted tiene una función que toma un parámetro que es potencialmente demasiado pequeño para lo que está pasando. Lo máximo que puede hacer es detectar cuándo podría ser un problema a través de un static_assert. Algo como esto:

static_assert(sizeof(std::streamsize) <= sizeof(long long), "Oops."); 

Para ser honesto, no me preocuparía. Las probabilidades son buenas de que long long sea el tamaño integral más grande que su compilador admita de forma nativa.

+0

Aparte del caso del tamaño del archivo exabytes, ¿puede ocurrir un problema durante la conversión a long long int? – Vincent

+0

@Vincent: No. Los tipos enteros se pueden convertir a un tipo entero más grande (o de igual tamaño) sin problema. –

+0

'streampos' implícitamente se convierte en' streamoff', por lo que puede pasarlo a algo esperando un 'long long'. La diferencia entre 'streampos' y' streamoff' es compatible con las codificaciones de caracteres con estado. – Potatoswatter

1

Solo pase el valor a cualquier función que necesite una larga duración. std::streamoff y std::streamsize son ambos tipos integrales con signo, y std::streampos es implícitamente convertible a std::streamoff.

editar: Supongo que afirmar que streamsize/streamoff no es más grande que long long no va a doler, en caso de que alguien aparezca con __int128 tamaños de archivo.

Cuestiones relacionadas