繁体   English   中英

C++ lambda function 引用传递问题

[英]C++ lambda function pass by reference problem

我使用 lambda function 将点云存储到向量的每个实例中。 即使我通过引用传递向量,当我尝试访问向量的每个实例时,我也会收到此错误:

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;

这不是编译错误,output 是:

for debug

当我尝试推动一个点时,我得到了这个错误。 Cloud::Ptrpcl::PointCloud<pcl::pointXYZI>::PtrPointpcl::PointXYZI

甚至我也删除了这些行:

    for (int i=0; i<2; i++) {
    Cloud::Ptr cloud(new Cloud);
    vector_cloud_frustums.push_back(cloud);
}

错误是一样的。

我假设Point , Cloud 和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;

您取消引用向量中的第一个元素并导致未定义的行为。 您可以在这个完整的示例中看到效果。

结论:您的代码中的问题不是 lambda 或捕获向量。 坏线是最后一条。 它调用未定义的行为。 在上面的链接中,您可以取消注释该行以查看它如何影响代码的 rest 的作用(即使之前出现了其他代码)。

解决方法是预先创建大小为 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*> ,除非有引入间接级别的理由。 如果有,请使用智能指针。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM