c++ - variable - unique_ptr reset




When moving a unique_ptr into a lambda, why is it not possible to call reset? (3)

  1. Why does this happen?

Because lambdas are by default non-mutable. Therefore all captured objects are const. reset is a non-const member function that modifies the unique pointer.

  1. Is it possible to capture the std::unique_ptr in another way which allows to call reset() within the lambda (with C++17 or later)?

Yes. Declare the lambda mutable:

[captures](arguments) mutable { body }
                      ^^^^^^^

This is possible since C++11 where lambdas were introduced. All captured non-const objects of a mutable lambda are non-const copies.

When moving std::unique_ptr into the lambda, it is not possible to call reset() on it, because it seems to be const then:

error C2662: void std::unique_ptr<int,std::default_delete<_Ty>>::reset(int *) noexcept': cannot convert 'this' pointer from 'const std::unique_ptr<int,std::default_delete<_Ty>>' to 'std::unique_ptr<int,std::default_delete<_Ty>> &
#include <memory>
int main()
{
    auto u = std::unique_ptr<int>();
    auto l = [v = std::move(u)]{
        v.reset(); // this doesn't compile
    };
}
  1. Why does this happen?
  2. Is it possible to capture the std::unique_ptr in another way which allows calling reset() within the lambda (with C++17 or later)?

  1. Why does this happen?

Because the function-call operator of a lambda ,

Unless the keyword mutable was used in the lambda-expression, the function-call operator is const-qualified and the objects that were captured by copy are non-modifiable from inside this operator() .

and

  1. Is it possible to capture the std::unique_ptr in another way which allows to call reset() within the lambda

You need to mark it mutable .

mutable: allows body to modify the parameters captured by copy, and to call their non-const member functions

e.g.

auto l = [v = std::move(u)]() mutable {
    v.reset();
};

Within the lambda its data members are immutable by default. You need to append the mutable specifier to the lambda expression.

As an alternative, you could capture the unique_ptr by reference, as for example:

#include <memory>

int main()
{
    auto u = std::unique_ptr<int>();
    auto l = [&v = u]{
        v.reset(); 
    };
}




capture-list