【问题标题】:Problem while iterating a vector using range-based loop使用基于范围的循环迭代向量时出现问题
【发布时间】:2020-05-10 20:42:57
【问题描述】:

我正在使用 PCL lib 进行 RANSAC 的基本实现。虽然,这里的问题仅与 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;
    }

不起作用的循环:

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 是一个向量(见下文)。因此,C++11 中引入的基于范围的循环应该可以工作,并且上面提到的两个循环应该是相同的,对吧?我想我在这里遗漏了一些东西。

变量详细信息:

在上面的代码中,var cloud 声明为:

 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

我在这里有一些理解问题,因此如果有人能提供帮助,那就太好了!

非常感谢!

【问题讨论】:

  • 两个循环应该做同样的事情。一个区别是auto elem : cloud-&gt;points 将复制向量中的每个元素,因此您可以将其更改为auto&amp; elem : cloud-&gt;pointsconst auto&amp; elem : cloud-&gt;points 来阻止它。如果这没有什么不同,我们真的需要minimal reproducible example
  • 这是什么意思:“循环不起作用”?为什么它不起作用?你有什么错误吗?还是什么?
  • 您还需要在continue; 之前增加index,而不仅仅是在循环结束时。

标签: c++ c++11 vector shared-ptr


【解决方案1】:

如果没有完整的代码示例,很难说,但两个循环有一点不同。我们删除的所有其他内容

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++;
}

在基于范围的 for 循环中,当 some_condition == true 时,索引不会增加。在基于索引的循环中,index 在每次迭代中递增。我想这两个循环实际上确实有相同的迭代次数,但是index 在基于范围的循环之后会有不同的值。

基于范围的循环的花哨设施仍然相当稀缺。如果您不想求助于 boost 或其他第三方库,我建议您在需要索引时使用基于索引的循环。当您不关心索引时,基于范围的循环很好。

【讨论】:

  • @blackbug 这不是我的本意。试着积极地看待它,学习是通过犯错来完成的。您应该觉得自己比以前知道的更多,那太好了;)
【解决方案2】:

第二个循环有一个continue,有机会跳过index++。如果发生这种情况,索引值将永远无法引用末尾的点。

看起来您希望index 在每次循环迭代时无条件地递增。最简单的更改是将continue 替换为

{
    index++;
    continue;
}

【讨论】:

    猜你喜欢
    • 2011-10-20
    • 2020-06-01
    • 1970-01-01
    • 2017-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多