Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why copy constructor is called in capture list of lambda

Tags:

c++

c++11

lambda

#include <iostream>
#include <vector>
#include <functional>

using namespace std;

struct B {
    B() {
        std::cout<<"B"<<std::endl;
    }
    
    B(B&& b2) {
        std::cout << "B&& from object moved" << b2.moved_ << std::endl;
        b2.moved_ = true;
    }
    
    B(const B&) {
        std::cout<<"const B&"<<std::endl;
    }
    
    // ~B(){
    //     std::cout<<"~B"<<std::endl;
    // }
    
    int bb=10;
    bool moved_=false;
};

struct FF {
    FF(std::function<void()> ff):ff_(std::move(ff)){}
    std::function<void()> ff_;
};

int main()
{
    std::vector<int> a{1,2,3};
    std::vector<FF> b{};
    B bb;
    std::transform(a.cbegin(), a.cend(), std::back_inserter(b), [x = std::move(bb)](auto const i) {
        
        return FF([xx = std::move(x), i]() {
            std::cout<<"FF"<<i<<std::endl;
        });
    });
    
    for(auto const& j:b) {
      j.ff_();
    }
    return 0;
}

As you can see from the code , my container b is a vector of FF, it accepts a function object as parameter . I want to confirm how lambda capture the parameter.

My question is why const& constructor will be called when xx=std::move(x) in capture list?

I think there should not be extra constructor.

like image 861
MengMeng Avatar asked Feb 03 '26 04:02

MengMeng


1 Answers

It's because the lambda is not mutable, contains const B x that can't be moved.

Easy fix

[x = std::move(bb)](auto const i) mutable {
like image 137
273K Avatar answered Feb 05 '26 19:02

273K



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!