risposta breve:
quasi mai
risposta lunga:
Ogni volta che devi avere un vettore di carattere maggiore di 2 GB su un sistema a 32 bit. In ogni altro caso d'uso, l'utilizzo di un tipo con segno è molto più sicuro rispetto all'utilizzo di un tipo senza segno.
esempio:
std::vector<A> data;
[...]
// calculate the index that should be used;
size_t i = calc_index(param1, param2);
// doing calculations close to the underflow of an integer is already dangerous
// do some bounds checking
if( i - 1 < 0 ) {
// always false, because 0-1 on unsigned creates an underflow
return LEFT_BORDER;
} else if( i >= data.size() - 1 ) {
// if i already had an underflow, this becomes true
return RIGHT_BORDER;
}
// now you have a bug that is very hard to track, because you never
// get an exception or anything anymore, to detect that you actually
// return the false border case.
return calc_something(data[i-1], data[i], data[i+1]);
L'equivalente firmato di size_t
è ptrdiff_t
, no int
. Ma l'utilizzo int
è ancora molto meglio nella maggior parte dei casi di size_t. ptrdiff_t
è long
su sistemi a 32 e 64 bit.
Questo significa che devi sempre convertire da e verso size_t ogni volta che interagisci con uno std :: containers, che non è molto bello. Ma in una conferenza nativa in corso gli autori di c ++ hanno menzionato che progettare std :: vector con un size_t non firmato è stato un errore.
Se il tuo compilatore ti dà avvisi su conversioni implicite da ptrdiff_t a size_t, puoi renderlo esplicito con la sintassi del costruttore:
calc_something(data[size_t(i-1)], data[size_t(i)], data[size_t(i+1)]);
se vuoi solo iterare una raccolta, senza limiti, usa l'intervallo basato su:
for(const auto& d : data) {
[...]
}
ecco alcune parole di Bjarne Stroustrup (autore C ++) per diventare nativi
Per alcune persone questo errore di progettazione firmato / non firmato nell'STL è una ragione sufficiente per non utilizzare lo std :: vector, ma una propria implementazione.
size_t
quando si dovrebbe può portare a bug di sicurezza .