краткий ответ:
почти никогда
длинный ответ:
Всякий раз, когда вам нужно, чтобы вектор символа был больше 2 ГБ в 32-битной системе. В любом другом случае использование подписанного типа намного безопаснее, чем использование неподписанного типа.
пример:
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]);
Эквивалентом size_t
со знаком является ptrdiff_t
, а не int
. Но использование int
все же намного лучше в большинстве случаев, чем size_t. ptrdiff_t
равно long
в 32- и 64-разрядных системах.
Это означает, что вам всегда нужно конвертировать в size_t и из него всякий раз, когда вы взаимодействуете с std :: Containers, что не очень красиво. Но на нативной конференции авторы c ++ отметили, что проектирование std :: vector с беззнаковым size_t было ошибкой.
Если ваш компилятор выдает предупреждения о неявных преобразованиях из ptrdiff_t в size_t, вы можете сделать это явным с помощью синтаксиса конструктора:
calc_something(data[size_t(i-1)], data[size_t(i)], data[size_t(i+1)]);
если вы хотите просто выполнить итерацию коллекции, без проверки границ, используйте диапазон на основе:
for(const auto& d : data) {
[...]
}
здесь несколько слов от Бьярна Страуструпа (автор C ++) на нативной
Для некоторых людей эта ошибка проектирования со знаком / без знака в STL является достаточной причиной, чтобы не использовать std :: vector, а вместо этого собственную реализацию.