Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lambda as an argument to std::vector::emplace_back

Tags:

c++

stl

stdvector

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.

like image 255
Haytham Avatar asked Sep 15 '26 03:09

Haytham


1 Answers

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.

like image 86
xskxzr Avatar answered Sep 17 '26 15:09

xskxzr



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!