C ++: Как мне «снять» не копируемые объекты (например, unique_ptr) с лямбды? - PullRequest
0 голосов
/ 06 марта 2019

Рассмотрим следующее:

unique_ptr<int> foo = make_unique<int>(42);

auto lambda = [bar = move(foo)]()
    {
        /* Do something with bar */
    };

lambda(); // No issues invoking this

cout << "*foo = " << *foo; //Attempts to dereference foo will segfault

Для захвата таких вещей, как unique_ptr, необходимо использовать std :: move, чтобы поддерживать уникальность unique_ptr. Но что делать, если я хочу использовать тот же умный указатель после разрушения лямбды? Использование foo даст segfault, и bar выходит за рамки этого.

Возможно, неортодоксальное использование лямбды, как мне вернуть мой unique_ptr? Это застряло в лямбде навсегда?

Ответы [ 2 ]

6 голосов
/ 06 марта 2019

Эту проблему можно решить путем захвата по ссылке.

auto lambda = [&]()
    {
        /* Do something with foo */
    };

// or

auto lambda = [&foo]()
    {
        /* Do something with foo */
    };

Позволяет использовать foo, фактически не перемещая его.

Единственное предостережение при этом:Вы должны обеспечить, чтобы время жизни лямбды не превышало время жизни указателя.Если это возможно, то вам следует рассмотреть метод совместного владения, например, вместо этого использовать std::shared_ptr.

3 голосов
/ 06 марта 2019

Но что делать, если я хочу использовать тот же умный указатель после разрушения лямбды?

Вы используете std::shared_ptr и не перемещаете то, что хотите использовать повторно.

auto foo = std::make_shared(42);
auto lambda = [bar=foo]()
{
    /* Do something with bar */
};
lambda(); // No issues invoking this
cout << "*foo = " << *foo; // also fine
...