如果我在lambda中删除容纳lambda的对象,那会发生什么
What exactly happens if I delete inside a lambda the object that holds that lambda?
我有一个回调系统,该回调系统在发生某些事情时会发出lambdas。要获得通知,必须将lambda注册到标识符,或者如果您不想再次通知,请取消注册。
我遇到的问题是,我已经注册了lambdas,将在该系统中取消注册,从而导致当前执行的lambda的破坏。而且我认为这不是安全的。但我不确定。
例如:
#include <map>
#include <functional>
#include <iostream>
int main() {
std::map<int, std::function<void ()>> m;
m[10] = [&m] () {
int i = m.size(); // Just cheking the internal state of the lambda
m.clear();
//i += m.size(); // If I uncomment this the std::cout is not working.
std::cout<< "What happens? " << i << std::endl;
};
m[10]();
return 0;
}
我看到的是,当我在m.clear()
之后检查Lambda的状态时,我会感到奇怪的行为(例如std::cout
不起作用)。您能解释一下在这些情况下到底会发生什么?
您将如何通过回调处理这些情况?在调用回调之前制作副本(似乎是不可以)?
考虑正在发生的事情:您正在存储用 std::function<void()>
中的 lambda expression生成的函数对象。
std::function
现在拥有生成的函数对象。它也位于std::map
中。
然后,您通过参考捕获相同的std::map
并在其上调用std::map::clear
,删除存储的std::function
。
来自cppreference.org
上的std::map::clear
文档:
从容器中删除所有元素。 使参考包含元素的任何参考,指针或迭代器无效。任何过去的迭代器仍然有效。
可以肯定地假设clear
std::map
无效存储在其中的数据。因此,使用存储在生成的函数对象中的数据不安全,并且可能导致未定义的行为。
这是A 粗糙简化您在做什么:
using func = std::function<void()>;
func f;
f = [&f]{ int a = 0; f.~func(); std::cout << a; };
相关文章:
- C++:对象将 lambda 存储到结构中,稍后调用该函数
- 从 lambda 返回的对象将丢失属性值
- 如何在C++中传递lambda函数内部的对象实例
- 带有自定义deleter的std::unique_ptr对象的大小(一个由ref捕获的lambda)
- 如何成功地将函数对象(或lambda)传递给trackbar回调的第二个参数(void*)
- Lambda:未评估上下文中未捕获的对象
- 使用 for_each 和 lambda 销毁已定位的对象
- 如何返回使用 lambda 模板化的对象?
- 为什么 lambda 对象中的局部变量是常量变量?
- lambda 对象构建成本高吗?
- 使用参数将仅可移动对象捕获到 lambda
- 使用 lambda/std::function 删除拥有该函数的对象
- 使用 lambda 和可变参数模板延迟初始化对象 - 任意传递值
- 如何在lambda中捕获此对象的变量
- C++ lambda 对象的地址作为函数的参数
- 在 C++ lambda 表达式中按值捕获是否需要将值与 lambda 对象一起复制
- 如何使c++ lambda对象的存储更高效?
- lambda对象相对于函数指针转换的生命周期
- 用lambda创建std::函数会导致对lambda对象的多余复制——为什么?
- 如何返回 lambda 对象