Использование авто в цикле С++
Я получаю предупреждение о несоответствии подписанного/неподписанного кода для следующего кода:
auto n = a.size();
for (auto i = 0; i < n; i++) {
}
Проблема состоит в том, что, назначая 0 на i
, она становится int
, а не size_t
.
Итак, что лучше:
size_t n = a.size();
for (size_t i = 0; i < n; i++) {
}
или это:
auto n = a.size();
for (size_t i = 0; i < n; i++) {
}
или, может быть, у вас есть лучшее решение? Мне нравится первый, потому что
он немного более последователен, он просто использует size_t
, а не как size_t
и auto
для этой же цели.
Ответы
Ответ 1
Цикл, основанный на диапазоне, может быть более чистым решением:
for (const auto& i : a)
{
}
Здесь i
является ссылкой const
на элемент контейнера a
.
В противном случае, если вам нужен индекс, или если вы не хотите перебирать весь диапазон, вы можете получить тип с decltype(a.size())
.
for (decltype(a.size()) i = 0; i < a.size(); ++i) {
}
Ответ 2
В зависимости от того, что вы хотите сделать внутри цикла и возможностей вашего компилятора, может быть лучшим решением для диапазона, основанного на контуре.
Все ваши представленные решения не являются плохими в большинстве ситуаций, с незначительными различиями
Ваше первое решение - на самом деле худший выбор, и именно то, что говорит ваш компилятор.
Второе решение лучше, но если вы хотите избежать прямого определения типов для простоты или некоторых будущих изменений, вы можете сделать следующее:
auto n = a.size();
for (decltype(n) i = 0; i < n; i++) {
}
Таким образом вы привязываете типы i
и n
, чтобы они всегда соответствовали друг другу.
Ответ 3
Если вы использовали правильный литерал, все будет хорошо: 0U. auto видит литерал типа int, так что это тип i. Добавьте U, и вместо этого вы увидите неподписанный int literal. В противном случае вы бы хотели использовать decltype, как предложили другие, тем более, что sizeof (size_t) может быть больше sizeof (int) (он находится в Windows, OS X и т.д., Если он работает в режиме с 64-разрядным интервалом).
Ответ 4
Для обсуждения:
auto n = a.size();
for (auto i = n-n; i<n; ++i) {
}
Обратите внимание, что для типов, меньших, чем int
, результат вычитания расширяется до int
(называемый целым продвижением).
Ответ 5
Попытка быть константной по возможности, я обычно пишу:
const auto n(a.size());
for (auto i = decltype(n){0}; i < n; ++i)
{
}
Это не очень сжато, но ясно, что вы хотите, чтобы переменная, инициализированная 0 из n
type (и n
была const
).
Ответ 6
for(auto n = a.size(), i = 0; i != n; ++i) {
}
..., вероятно, является самым чистым решением, если вам нужен доступ к индексу, а также к фактическому элементу.
Update:
for(auto n = a.size(), i = n*0; i != n; ++i) {
}
Было бы обходным путем для комментария Ричарда Смита, хотя он больше не выглядит таким чистым.