将 unique_ptr 移入 lambda 时,为什么无法调用重置?
When moving a unique_ptr into a lambda, why is it not possible to call reset?
将 std::unique_ptr
移动到 lambda 中时,无法对其调用 reset()
,因为它似乎是常量:
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
};
}
- 为什么会这样?
- 是否有可能以另一种允许在 lambda 中调用
reset()
的方式捕获 std::unique_ptr
(使用 C++17 或更高版本)?
- Why does this happen?
因为 function-call 运算符 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()
.
和
- Is it possible to capture the
std::unique_ptr
in another way which allows to call reset()
within the lambda
您需要标记它mutable
。
mutable: allows body to modify the parameters captured by copy, and to call their non-const member functions
例如
auto l = [v = std::move(u)]() mutable {
v.reset();
};
- Why does this happen?
因为默认情况下 lambda 是 non-mutable。因此所有捕获的对象都是常量。 reset
是一个non-const修改唯一指针的成员函数。
- 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)?
是的。声明 lambda 可变:
[captures](arguments) mutable { body }
^^^^^^^
这是可能的,因为 C++11 引入了 lambda。可变 lambda 的所有捕获 non-const 个对象都是 non-const 个副本。
要改变 lambda 的 "member",您需要 mutable
关键字:
auto l = [v = std::move(u)] () mutable {
v.reset();
};
在 lambda 中,它的数据成员默认是不可变的。您需要将 mutable
说明符附加到 lambda 表达式。
作为替代方案,您可以通过引用捕获 unique_ptr
,例如:
#include <memory>
int main()
{
auto u = std::unique_ptr<int>();
auto l = [&v = u]{
v.reset();
};
}
将 std::unique_ptr
移动到 lambda 中时,无法对其调用 reset()
,因为它似乎是常量:
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
};
}
- 为什么会这样?
- 是否有可能以另一种允许在 lambda 中调用
reset()
的方式捕获std::unique_ptr
(使用 C++17 或更高版本)?
- Why does this happen?
因为 function-call 运算符 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 thisoperator()
.
和
- Is it possible to capture the
std::unique_ptr
in another way which allows to callreset()
within the lambda
您需要标记它mutable
。
mutable: allows body to modify the parameters captured by copy, and to call their non-const member functions
例如
auto l = [v = std::move(u)]() mutable {
v.reset();
};
- Why does this happen?
因为默认情况下 lambda 是 non-mutable。因此所有捕获的对象都是常量。 reset
是一个non-const修改唯一指针的成员函数。
- 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)?
是的。声明 lambda 可变:
[captures](arguments) mutable { body }
^^^^^^^
这是可能的,因为 C++11 引入了 lambda。可变 lambda 的所有捕获 non-const 个对象都是 non-const 个副本。
要改变 lambda 的 "member",您需要 mutable
关键字:
auto l = [v = std::move(u)] () mutable {
v.reset();
};
在 lambda 中,它的数据成员默认是不可变的。您需要将 mutable
说明符附加到 lambda 表达式。
作为替代方案,您可以通过引用捕获 unique_ptr
,例如:
#include <memory>
int main()
{
auto u = std::unique_ptr<int>();
auto l = [&v = u]{
v.reset();
};
}