2012-10-08 20 views
7

Per misurare la posizione/gli offset/le dimensioni dei flussi, lo standard specifica std::streampos, std::streamoff e std::streamsize, ma sono stati definiti per l'implementazione.std :: streampos, std :: streamoff e std :: streamsize to long long int?

Come convertire questi tipi in long long int in modo sicuro e portatile? (ad esempio per misurare una dimensione del file e inserirla in una funzione che richiede un lungo long int come argomento)

risposta

5

Bene, per quanto riguarda C++ 98/03, lo non èlong long int. Quindi presumo che tu stia chiedendo di C++ 11.

Il streamsize e streamoff sono tenuti ad essere typedef di un tipo integrale (streampos non è un intero, in modo da non passerà che a tutto ciò che richiede un long long). Poiché i tipi interi sono tipi base, possono essere definiti solo da C++ o come definizione specifica del compilatore.

Quindi, l'unica domanda è questa: sono questi typedef più grandi di long long? Tutti i tipi di integrale sono convertibili in un tipo di dimensioni maggiori o uguali (firmati/non firmati nonostante, ma tutti i tipi qui sono firmati, quindi nessun problema). Ma se è più grande ... cosa hai intenzione di fare al riguardo?

Supponendo che non sia possibile modificare la firma della funzione a cui si sta "iniettando" (in caso contrario, non c'è motivo di non prendere semplicemente streamsize come tipo di parametro ed evitare così il problema), non si Ho qualche opzione. Si dispone di un valore di dati che è maggiore di quello che richiede la funzione. Non c'è modo di aggirarlo qui.

È possibile eseguire un static_cast in un long long per chiudere il compilatore, ma questo non aiuta se le dimensioni effettive non possono rientrare in un long long.

In definitiva, questo è un problema irrisolvibile. Hai una funzione che accetta un parametro che è potenzialmente troppo piccolo per quello che stai passando. Il massimo che puoi fare è rilevare quando potrebbe essere un problema tramite static_assert. Qualcosa del genere:

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

A dire il vero, non me ne preoccuperei. Le probabilità sono buone che long long sarà la dimensione integrale più grande che il compilatore supporta nativamente.

+0

A parte il caso della dimensione del file di exabyte, può verificarsi un problema durante la conversione in long long int? – Vincent

+0

@Vincent: No. I tipi interi possono essere convertiti in un tipo intero più grande (o uguale) senza problemi. –

+0

'streampos' converte implicitamente in' streamoff', quindi potresti passarlo a qualcosa che si aspetta un 'molto lungo'. La differenza tra 'streampos' e' streamoff' è il supporto per codifiche di caratteri stateful. – Potatoswatter

1

Basta passare il valore a qualsiasi funzione che richiede molto tempo. std::streamoff e std::streamsize sono entrambi tipi integrali firmati e std::streampos è implicitamente convertibile in std::streamoff.

modifica: Suppongo che asserire che streamsize/streamoff non è più grande di long long non farà male, nel caso qualcuno si presenti con dimensioni di file __int128.

Problemi correlati