【发布时间】:2018-11-02 14:51:18
【问题描述】:
我不会假装我对 lambdas 非常有经验,但是对于这个看似简单的问题,我认为我需要更深入地了解它的实际工作原理。
我正在外部作用域上实例化一个对象,并使用 2 个 lambda,我尝试修改该指针。
// Object to be manipulated
Object* obj= nullptr;
// To be invoked externally in order to construct and initialize obj
std::function<void(std::function<void(const String&)>)> SetObject
= [&obj](std::function<void(const String&)> func)
{
obj= new Object();
// ... Initialize Values
};
// To be invoked externally to reset and delete obj
std::function<void()> ResetObject
= [&obj]()
{
if(obj)
{
delete obj;
obj= nullptr;
}
};
主代码执行并首先调用 RESET 方法,然后再创建一个新的 Object 实例。假设“主”代码无法访问、读取或修改 obj - 因此依赖于盲重置。
预期结果:第一次调用重置表达式时,对 obj 的检查应该返回 false,因为 obj 在外部范围内被设置为 nullptr -- 没有任何反应。
实际结果:到执行reset时,obj不再指向NULL,检查返回true并调用delete,导致访问冲突。
我想知道我正在尝试做的任何事情是否一开始就是一个无效的操作,或者我捕获变量的方式是否不正确。我尝试按值捕获指针,将函数设置为可变,并出于绝望将引用和值捕获相结合。
编辑:在这一点上,我相信对象的范围是其他人指出的罪魁祸首。我将尝试解决方法 记住这一点并报告回来。
【问题讨论】:
-
当 lambda 被调用时,
obj是否超出范围? -
是的,我们确实需要知道该声明的范围。 MCVE 会让这一点显而易见。
-
请编辑您的问题以包含minimal reproducible example
-
对不起,我试图尽可能地精简它,因为我不允许共享此代码的上下文。我可以说我展示的代码(以及许多其他 lambda 表达式)位于应用程序首次运行时调用的初始化函数中。如果信息不足,请随时删除问题。
-
是否有充分的理由不能将
obj换成智能指针,即std::unique_ptr<Object>?