Проблема при итерации вектора с использованием цикла на основе диапазона - PullRequest
1 голос
/ 24 января 2020

Я делаю базовую c реализацию RANSA C с использованием PCL lib. Хотя этот вопрос касается только концепций C ++.

Я перебираю облако точек двумя способами; один работает отлично, а другой перебирает менее половины баллов. Я просто хочу понять причину, по которой один из двух не работает.

Рабочий один:

    for (int index=0; index < cloud->points.size(); index++)
    {
        float distance = abs(A * cloud->points[index].x + B * cloud->points[index].y + C * cloud->points[index].z + D) / sqrt(A * A + B * B + C * C);

        // Check for the two points set above, if present ignore
        if (set_inliers.count(index) > 0)
            continue;

        // If distance is smaller than threshold count it as inlier
        if (distance <= distanceTol)
            set_inliers.insert(index);

        std::cout << "Point Number: " << index << std::endl;
    }

l oop, который не работает:

int index = 0;

for (auto elem : cloud->points)
{
    float distance = abs(A * elem.x + B * elem.y + C * elem.z + D) / sqrt(A * A + B * B + C * C);

    // Check for the two points set above, if present ignore
    if (set_inliers.count(index) > 0)
        continue;

    // If distance is smaller than threshold count it as inlier
    if (distance <= distanceTol)
        set_inliers.insert(index);

    std::cout << "Point Number: " << index << std::endl;
    index++;
} 

cloud-> points - это вектор (см. Ниже). Таким образом, основанный на диапазоне l oop, введенный в C ++ 11, должен работать, и оба упомянутых выше цикла должны быть идентичны, верно? Я думаю, что я что-то здесь упустил.

Детали переменной:

В приведенном выше коде облако var объявляется как:

 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud

Ptr - это вектор следующего :

 std::vector<pcl::PointXYZ, Eigen::aligned_allocator<pcl::PointXYZ>

cloud-> points определяется как:

 std::vector<PointT, Eigen::aligned_allocator<PointT> > pcl::PointCloud< PointT >::points

Для справки: PCL Point Cloud Reference

У меня есть понимание здесь, и поэтому будет здорово, если кто-то сможет помочь!

Большое спасибо!

Ответы [ 2 ]

4 голосов
/ 24 января 2020

Без полного примера вашего кода трудно сказать, но есть одна вещь, которая отличается в двух циклах. Все остальное удалено у нас

for (int index=0; index < cloud->points.size(); index++) { 
    if (some_condition) continue;
    // use index
}

против

int index = 0;
for (auto elem : cloud->points) {
    if (some_contition) continue;
    // use index
    index++;
}

В основанном на диапазоне для -l oop индекс не увеличивается при some_condition == true. В индексе на основе l oop, index увеличивается на каждую итерацию. Я предполагаю, что два l oop на самом деле имеют одинаковое количество итераций, но index будет иметь другое значение после того, как l oop.

Причудливые возможности для циклов на основе диапазона по-прежнему довольно мало Если вы не хотите прибегать к помощи boost или других сторонних библиотек, я бы предложил использовать циклы на основе индекса, когда вам нужен индекс. Циклы на основе диапазона хороши, когда вам нет дела до индекса.

1 голос
/ 24 января 2020

Второй л oop имеет continue, возможность пропустить index++. Если это когда-либо произойдет, на точки в конце никогда не будет ссылаться значение индекса.

Похоже, вы хотите, чтобы index увеличивался с каждой итерацией l oop, безусловно. Самым простым изменением было бы заменить continue на

{
    index++;
    continue;
}
...