C++ 将唯一的_ptr移动到lambda中时,为什么不能调用reset?
将C++ 将唯一的_ptr移动到lambda中时,为什么不能调用reset?,c++,c++11,lambda,unique-ptr,capture-list,C++,C++11,Lambda,Unique Ptr,Capture List,将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>&g
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>> &
错误C2662:void std::unique_ptr::reset(int*)noexcept::无法将“this”指针从“const std::unique_ptr”转换为“std::unique_ptr”&
#包括
int main()
{
自动u=std::unique_ptr();
自动l=[v=std::移动(u)]{
v、 reset();//这不会编译
};
}
std::unique_ptr
,从而允许在lambda中调用reset()
(使用C++17或更高版本)mutable
,否则函数调用操作符是const限定的,并且通过copy捕获的对象在此操作符()中是不可修改的
及
是否可以通过另一种方式捕获std::unique_ptr
,从而允许在lambda中调用reset()
您需要将其标记为mutable
可变:允许主体修改复制捕获的参数,并调用其非常量成员函数
e、 g
为什么会发生这种情况
因为lambda在默认情况下是不可变的。因此,所有捕获的对象都是常量<代码>重置
是一个修改唯一指针的非常量成员函数
[captures](arguments) mutable { body }
^^^^^^^
这是可能的,因为C++11引入了lambda。可变lambda的所有捕获的非常量对象都是非常量副本。要对lambda的“成员”进行变异,需要可变关键字:
auto l = [v = std::move(u)] () mutable {
v.reset();
};
在lambda中,其数据成员在默认情况下是不可变的。您需要将mutable
说明符附加到lambda表达式中
或者,您可以通过引用捕获唯一的\u ptr
,例如:
#include <memory>
int main()
{
auto u = std::unique_ptr<int>();
auto l = [&v = u]{
v.reset();
};
}
#包括
int main()
{
自动u=std::unique_ptr();
自动l=[&v=u]{
v、 重置();
};
}
很可能lambda将超过它声明的范围,因此引用捕获将dangle@Caleth这取决于上下文,但为什么呢?当lambda超出范围时,v
不会自动重置吗?@L.F.是的,它会重置,并且它的析构函数与const
ptr一起工作。但是,如果指针的生命周期需要在作用域结束之前结束(或者应该分配另一个指针,或者应该将托管对象的所有权转移到另一个唯一的\u ptr),则需要非常量唯一的\u ptr。
auto l = [v = std::move(u)] () mutable {
v.reset();
};
#include <memory>
int main()
{
auto u = std::unique_ptr<int>();
auto l = [&v = u]{
v.reset();
};
}