I came across code that passes a lambda as an argument to emplace_back, which confused me. So I wrote a small test to validate the syntax like this:
struct A
{
int a;
A(){cout<<"constructed"<<endl;}
A(const A& other){a = other.a; cout<<"copied"<<endl;}
A(const A&& other){a = other.a; cout<<"moved"<<endl;}
};
int main()
{
vector<A> vec;
vec.emplace_back(
[]{A a;
a.a = 1;
return a;
}());
A a2;
a2.a = 2;
vec.emplace_back(std::move(a2));
return 0;
}
I have two questions: 1) Can someone clarify how a lambda can be passed as an argument to emplace_back? I had only seen constructor arguments being passed to emplace back in the past. 2) The output was:
constructed
moved
constructed
moved
copied
Where is the last copied coming from? Why aren't the two approaches equivalent.
Can someone clarify how a lambda can be passed as an argument to emplace_back?
You are not passing a lambda. Instead, you pass the result of calling the lambda.
Where is the last copied coming from?
It comes from the vector. When a2 is inserted to vec, a reallocation occurs, which reallocates memory and copy the objects in the old memory to the new memory.
If you specify the move constructor as noexcept, i.e.
A(const A&& other) noexcept {a = other.a; cout<<"moved"<<endl;}
then std::vector will move the objects during reallocation instead of copying, and you can see the last copy becomes move.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With