C++ lambda函数引用传递问题
C++ lambda function pass by reference problem
我使用 lambda 函数将点云存储到向量的每个实例中。即使我通过引用传递向量,当我尝试访问向量的每个实例时,我也会收到此错误:
typename boost::detail::sp_member_access<T>::type boost::shared_ptr<T>::operator->() const [with T = pcl::PointCloud<pcl::PointXYZI>; typename boost::detail::sp_member_access<T>::type = pcl::PointCloud<pcl::PointXYZI>*]: Assertion `px != 0' failed.
我的代码:
int size_ = 2;
std::vector<Cloud::Ptr> vector_cloud(size_);
for(int i=0; i<size_; i++)
{
Cloud::Ptr cloud_(new Cloud);
vector_cloud.push_back(cloud_);
}
auto fonk1 = [ &vector_cloud, size_]()
{
for(int i=0; i<size_; i++)
{
std::cout << "for debug" << std::endl;
Point p;
p.x = 0;
p.y = 0;
p.z = 0;
p.intensity = 0;
vector_cloud[i]->points.push_back(p);
}
};
fonk1();
std::cout << "Cloud size: " << vector_cloud[0]->size() << std::endl;
不是编译错误,输出为:
for debug
当我尝试推送一个点时出现此错误。 Cloud::Ptr
是 pcl::PointCloud<pcl::pointXYZI>::Ptr
而 Point
是 pcl::PointXYZI
我什至删除了那些行:
for (int i=0; i<2; i++) {
Cloud::Ptr cloud(new Cloud);
vector_cloud_frustums.push_back(cloud);
}
错误是一样的。
我假设 Point
、Cloud
和 Cloud::Ptr
是这样的:
struct Point {
int x,y,z,intensity;
};
struct Cloud {
std::vector<Point> points;
void push_back(const Point& p) { points.push_back(p);}
using Ptr = Cloud*;
size_t size() const { return points.size(); }
};
事实证明它们是另外一回事,但这对答案来说并不重要。
您的代码中的问题是您创建了一个大小为 2 的向量:
std::vector<Cloud::Ptr> vector_cloud(size_);
然后在这个循环中再压入 2 个元素:
for(int i=0; i<size_; i++)
{
Cloud::Ptr cloud_(new Cloud);
vector_cloud.push_back(cloud_);
}
前两个元素不指向 Cloud
的实例。只有最后两个指向 Cloud
。然后在你代码的最后一行:
std::cout << "Cloud size: " << vector_cloud[0]->size() << std::endl;
您取消引用向量中的第一个元素并导致未定义的行为。可以在这个complete example.
中看到效果
结论:您的代码中的问题不是 lambda 或捕获向量。坏线是最后一条。它调用未定义的行为。在上面的 link 中,您可以取消注释该行以查看它如何影响其余代码的作用(即使其他代码出现在前面)。
解决方法是预先创建大小为 2 的向量,然后使用 或 使用 push_back
访问这些元素,但不能同时访问这两个元素。例如:
int size_ = 2;
std::vector<Cloud::Ptr> vector_cloud; // empty vector !!
vector_cloud.reserve(size_); // reserve space
for(int i=0; i<size_; i++)
{
Cloud::Ptr cloud_(new Cloud);
vector_cloud.push_back(cloud_); // push elements
}
PS 您很可能不需要代码中的任何指针。使用 std::vector<Cloud>
而不是 std::vector<Cloud*>
,除非有理由引入间接级别。当有的时候,使用智能指针。
我使用 lambda 函数将点云存储到向量的每个实例中。即使我通过引用传递向量,当我尝试访问向量的每个实例时,我也会收到此错误:
typename boost::detail::sp_member_access<T>::type boost::shared_ptr<T>::operator->() const [with T = pcl::PointCloud<pcl::PointXYZI>; typename boost::detail::sp_member_access<T>::type = pcl::PointCloud<pcl::PointXYZI>*]: Assertion `px != 0' failed.
我的代码:
int size_ = 2;
std::vector<Cloud::Ptr> vector_cloud(size_);
for(int i=0; i<size_; i++)
{
Cloud::Ptr cloud_(new Cloud);
vector_cloud.push_back(cloud_);
}
auto fonk1 = [ &vector_cloud, size_]()
{
for(int i=0; i<size_; i++)
{
std::cout << "for debug" << std::endl;
Point p;
p.x = 0;
p.y = 0;
p.z = 0;
p.intensity = 0;
vector_cloud[i]->points.push_back(p);
}
};
fonk1();
std::cout << "Cloud size: " << vector_cloud[0]->size() << std::endl;
不是编译错误,输出为:
for debug
当我尝试推送一个点时出现此错误。 Cloud::Ptr
是 pcl::PointCloud<pcl::pointXYZI>::Ptr
而 Point
是 pcl::PointXYZI
我什至删除了那些行:
for (int i=0; i<2; i++) {
Cloud::Ptr cloud(new Cloud);
vector_cloud_frustums.push_back(cloud);
}
错误是一样的。
我假设 Point
、Cloud
和 Cloud::Ptr
是这样的:
struct Point {
int x,y,z,intensity;
};
struct Cloud {
std::vector<Point> points;
void push_back(const Point& p) { points.push_back(p);}
using Ptr = Cloud*;
size_t size() const { return points.size(); }
};
事实证明它们是另外一回事,但这对答案来说并不重要。
您的代码中的问题是您创建了一个大小为 2 的向量:
std::vector<Cloud::Ptr> vector_cloud(size_);
然后在这个循环中再压入 2 个元素:
for(int i=0; i<size_; i++)
{
Cloud::Ptr cloud_(new Cloud);
vector_cloud.push_back(cloud_);
}
前两个元素不指向 Cloud
的实例。只有最后两个指向 Cloud
。然后在你代码的最后一行:
std::cout << "Cloud size: " << vector_cloud[0]->size() << std::endl;
您取消引用向量中的第一个元素并导致未定义的行为。可以在这个complete example.
中看到效果结论:您的代码中的问题不是 lambda 或捕获向量。坏线是最后一条。它调用未定义的行为。在上面的 link 中,您可以取消注释该行以查看它如何影响其余代码的作用(即使其他代码出现在前面)。
解决方法是预先创建大小为 2 的向量,然后使用 或 使用 push_back
访问这些元素,但不能同时访问这两个元素。例如:
int size_ = 2;
std::vector<Cloud::Ptr> vector_cloud; // empty vector !!
vector_cloud.reserve(size_); // reserve space
for(int i=0; i<size_; i++)
{
Cloud::Ptr cloud_(new Cloud);
vector_cloud.push_back(cloud_); // push elements
}
PS 您很可能不需要代码中的任何指针。使用 std::vector<Cloud>
而不是 std::vector<Cloud*>
,除非有理由引入间接级别。当有的时候,使用智能指针。