Лямбда в качестве аргумента для std :: vector :: emplace_back - PullRequest
0 голосов
/ 27 апреля 2018

Я наткнулся на код, который передает лямбду в качестве аргумента emplace_back, что меня смутило. Поэтому я написал небольшой тест для проверки синтаксиса:

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;
}

У меня есть два вопроса: 1) Может кто-нибудь уточнить, как лямбда может быть передана в качестве аргумента emplace_back? Я видел только те аргументы конструктора, которые передавались в прошлое. 2) Вывод был:

constructed
moved
constructed
moved
copied

Откуда поступает последняя копия? Почему два подхода не эквивалентны.

Ответы [ 2 ]

0 голосов
/ 27 апреля 2018

Может кто-нибудь прояснить, как лямбда может быть передана в качестве аргумента emplace_back?

Вы не проходите лямбду. Вместо этого вы передаете результат вызова лямбды.

Откуда поступает последний скопированный файл?

Это происходит от вектора. Когда a2 вставляется в vec, происходит перераспределение, которое перераспределяет память и копирует объекты из старой памяти в новую память.

Если вы укажете конструктор перемещения как noexcept, т.е.

A(const A&& other) noexcept {a = other.a; cout<<"moved"<<endl;}

затем std::vector будет перемещать объекты во время перераспределения вместо копирования, и вы можете видеть, что последняя копия становится перемещенной.

0 голосов
/ 27 апреля 2018

Обратите внимание на () после определения лямбды, которое вызывает лямбду. Этот код эквивалентен следующему:

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

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

    // ...
}

Что, поскольку лямбда имеет пустой захват, эквивалентно этому:

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

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

    // ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...