короткий ответ:
почти никогда
длинный ответ:
Всякий раз, когда вам нужно иметь вектор char больше, чем 2gb в 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, а вместо этого собственную реализацию.
size_t
когда вы должны можете привести к ошибкам безопасности .