krótka odpowiedź:
prawie nigdy
długa odpowiedź:
Ilekroć musisz mieć wektor char większy niż 2 GB w systemie 32-bitowym. W każdym innym przypadku użycie podpisanego typu jest znacznie bezpieczniejsze niż użycie niepodpisanego typu.
przykład:
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]);
Podpisany odpowiednik size_t
to ptrdiff_t
nie int
. Ale int
w większości przypadków używanie jest znacznie lepsze niż size_t. ptrdiff_t
jest long
w systemach 32 i 64-bitowych.
Oznacza to, że zawsze musisz konwertować do iz size_t za każdym razem, gdy wchodzisz w interakcje ze std :: container, co nie jest zbyt piękne. Ale podczas trwającej konferencji natywnej autorzy c ++ wspomnieli, że zaprojektowanie std :: vector z niepodpisanym size_t było błędem.
Jeśli Twój kompilator wyświetla ostrzeżenia o niejawnych konwersjach z ptrdiff_t na size_t, możesz to wyraźnie wyrazić za pomocą składni konstruktora:
calc_something(data[size_t(i-1)], data[size_t(i)], data[size_t(i+1)]);
jeśli chcesz po prostu iterować kolekcję, bez sprawdzania granic, użyj zakresu opartego na:
for(const auto& d : data) {
[...]
}
tutaj kilka słów od Bjarne Stroustrup (autor C ++) na temat przejścia na język ojczysty
Dla niektórych osób ten błąd projektu podpisany / niepodpisany w STL jest wystarczającym powodem, aby nie używać std :: vector, ale zamiast własnej implementacji.
size_t
kiedy należy może prowadzić do błędów bezpieczeństwa .