Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access variables in lambda function? (c++)

I'm new to cpp, so this may seem trivial, but I want to change local variable (bool done1) in lambda function, but it seems like it's not doing anything to the varialbe and it's still true. Any suggestions? Thanks

    bool done1 = true;
    bool done2 = true;
    bool done3 = true;

    // associates each point to the nearest center
    std::thread thread_1([this](vector<Point> points,bool done) {
        for(int i = 0; i < total_points/3; i++) {
            int id_old_cluster = points[i].getCluster();
            int id_nearest_center = getIDNearestCenter(points[i]);
            if (id_old_cluster != id_nearest_center) {
                if (id_old_cluster != -1){
                    clusters[id_old_cluster].removePoint(points[i].getID());
                }
                points[i].setCluster(id_nearest_center);
                clusters[id_nearest_center].addPoint(points[i]);
                done = false;
            }
        }
    },points, done1);
like image 259
David Avatar asked Apr 27 '26 13:04

David


1 Answers

If you want to change done1 in your thread, lambda should take bool by reference, and done1 must be wrapped into reference_wrapper when thread ctor is called:

std::thread thread_1([this](vector<Point> points,bool& done) { // take by reference
    for(int i = 0; i < total_points/3; i++) {
        int id_old_cluster = points[i].getCluster();
        //...
            done = false;
        }
    }
},points, std::ref(done1) ); // <--- std::ref

Another option is to capture done1 by reference, then lambda takes only one parameter:

[this,&done1](vector<Point> points) {
   //...
   done1 = true;
}, points);

Your lambda modifies vector of points, but now it is copy, so passed vector is not affected when thread ends. You need to pass points also by reference:

std::thread thread_1([this](vector<Point>& points,bool& done) { // both args by ref
        for(int i = 0; i < total_points/3; i++) {
            int id_old_cluster = points[i].getCluster();
            //...
                done = false;
            }
        }
    }, std::ref(points), std::ref(done1) ); // <--- std::ref 2x
like image 151
rafix07 Avatar answered Apr 30 '26 05:04

rafix07