简体   繁体   English

Lambda作为std :: vector :: emplace_back的参数

[英]Lambda as an argument to std::vector::emplace_back

I came across code that passes a lambda as an argument to emplace_back, which confused me. 我遇到了将lambda作为参数传递给emplace_back的代码,这让我很困惑。 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? 我有两个问题:1)有人可以澄清一个lambda如何作为emplace_back的参数传递? I had only seen constructor arguments being passed to emplace back in the past. 我过去只看过构造函数参数传递给了emplace。 2) The output was: 2)输出结果是:

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? 有人可以澄清lambda如何作为emplace_back的参数传递?

You are not passing a lambda. 你没有传递一个lambda。 Instead, you pass the result of calling the lambda. 相反,您传递调用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. a2插入到vec ,会发生重新分配,重新分配内存并将旧内存中的对象复制到新内存。

If you specify the move constructor as noexcept , ie 如果将移动构造函数指定为noexcept ,即

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. 然后std::vector将在重新分配期间移动对象而不是复制,您可以看到最后一个副本变为移动。

Notice the () after the lambda definition, which calls the lambda. 注意lambda定义之后的() ,它调用lambda。 This code is equivalent to the following: 此代码等效于以下内容:

int main()
{
    auto make_a = []()
    {
        A a;
        a.a = 1;
        return a;
    };

    vector<A> vec;
    vec.emplace_back(make_a());

    // ...
}

Which, since the lambda has empty capture, is equivalent to this: 其中,因为lambda具有空捕获,相当于:

A make_a()
{
    A a;
    a.a = 1;
    return a;
}

int main()
{
    vector<A> vec;
    vec.emplace_back(make_a());

    // ...
}

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

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