当要使用for循环对一个容器进行遍历,并修改容器内数据值的时候,一般的做法就是,首先通过size()方法获取到容器内数据的数量,然后循环遍历每个数据,并对容器内的值进行修改。如下示例代码所示:
void normalExample(pcl::PointCloud<pcl::PointXYZL>::Ptr pttest) {
//以第一个点坐标为偏移量
pcl::PointXYZ offset;
offset.x = pttest->at(0).x;
offset.y = pttest->at(0).y;
offset.z = pttest->at(0).z;
//获取总点数
int ptnum = pttest->size();
//对整个点云进行偏移
for (int i = 0; i < ptnum; i++) {
pttest->points[i].x -= offset.x;
pttest->points[i].y -= offset.y;
pttest->points[i].z -= offset.z;
}
}
然而,基于c++11新特性,我们可以有新的(应该更好)方法来实现这一操作。我们可以在for循环时候,结合auto类型以及引用的方式,来实现更高效的数据更新操作。如下示例代码所示:
void improvedExample(pcl::PointCloud<pcl::PointXYZL>::Ptr pttest) {
//以第一个点坐标为偏移量
pcl::PointXYZ offset;
offset.x = pttest->at(0).x;
offset.y = pttest->at(0).y;
offset.z = pttest->at(0).z;
//对整个点云进行偏移
for (auto& pt : pttest->points) {
pt.x -= offset.x;
pt.y -= offset.y;
pt.z -= offset.z;
}
}
对比两个示例,可以看出:在改进的示例中,我们可以不用再提前获取容器内数据的数量,而是通过迭代和引用的方式,对容器内的每个数据进行更新操作。
在这里,也许你还会注意到,获取pcl点类型的值有两种方式:一种是at(i),一种是points[i]。这两种方法都可以获取到点的值。区别在于,at(i)只能获取,不能写,相当于只读;而points[i]既可以读,也可以写。