Подтвердить что ты не робот

Использование авто в цикле С++

Я получаю предупреждение о несоответствии подписанного/неподписанного кода для следующего кода:

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 для этой же цели.

4b9b3361

Ответ 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) {
}

Было бы обходным путем для комментария Ричарда Смита, хотя он больше не выглядит таким чистым.