Авто не удалось для векторного размера - PullRequest
0 голосов
/ 26 мая 2018

Я пытаюсь использовать auto для вывода типа.

for (auto i = remaining_group.size() - 1; i >= 0; --i) {
    std::cout << i;
}

Я получаю очень большое число, например 18446744073709534800, которое не ожидается.Когда я изменяю auto на int, это ожидаемое число от 0 до 39.

Есть ли какая-то причина, по которой auto здесь потерпит неудачу?

remaining_group Типstd::vector<lidar_point>, а lidar_point имеет следующую структуру:

struct LidarPoint {
  float x;
  float y;
  float z;
  uint8_t field1;
  double field2;
  uint8_t field3;
  uint16_t field4;
}

Ответы [ 3 ]

0 голосов
/ 26 мая 2018

Простое воспроизведение задачи:

#include <iostream>

size_t size()  {return 1;}

int main() {
   for (auto i = size() - 1; i >= 0; --i) {
    std::cout << i << std::endl;
   }
}

size() полученный тип size_t и буквальная константа 1 будут преобразованы в size_t, в результате auto станет size_t,который не может быть меньше нуля, что приводит к бесконечному циклу и недостаточному значению i.

0 голосов
/ 26 мая 2018

Если вам нужен обратный индексный цикл, используйте operator -->

Когда вы пишете нормальный индексный цикл, вы пишете его с помощью 0, size и <.

Когда вы пишете нормальный обратный индексный цикл, все становится немного странно: вам нужны size - 1, >=, 0, и вы не можете использовать unsigned index, потому что unsigned i всегда >= 0, так что ваша проверка i >= 0 всегда возвращает true, ваш цикл может работать вечно.

С ложным оператором «идет», вы можете использовать 0, size и > для записи обратного индексного цикла, и не имеет значения, если i подписано или не подписано:

for (auto i = a.size(); i --> 0; ) //or just i--, or i --> 1, i --> 10...
    std::cout << i << ' ';
0 голосов
/ 26 мая 2018

При использовании auto тип i будет std::vector::size_type, что является целым типом без знака.Это означает, что условие i >= 0; будет всегда true, и если произойдет переполнение , вы получите несколько больших чисел.

Целочисленная арифметика без знака всегда выполняется по модулю 2 n где n - количество битов в этом конкретном целом числе.Например, для unsigned int, добавление одного к UINT_MAX дает ​0, а вычитание одного из 0 дает UINT_MAX.

...