C++11 λ 本身是否受 RAII 自动释放的影响
Are C++11 lambdas themselves subject to RAII automatic deallocation?
我想编写一个类方法,可以选择接受lambda来自定义其行为。 所以在使用这个类时,我想知道我是否需要担心 lambda 本身超出范围?
lambda 不会引用任何外部变量,所以我不担心变量的范围,只担心 lambda 本身的范围,我会在类中存储对它的引用。
我是否需要担心 lambda 本身是如何/在哪里创建的?
在狭隘的情况下,引用不会延长所引用事物的生存期。
使用对生存期已过期的事物的引用是未定义的行为。
无状态 lambda 的未定义行为可能是"我什至不使用我的this
指针",所以你可能没问题。 但是,如果您知道 lambda 将是无状态的,则可以改为存储函数指针。
现在,为了存储实际的 lambda,您的类必须在该 lambda 类型上进行模板化。 如果它是一个无状态的lambda,它几乎肯定会比对该lambda的引用一样小(或更小)。 那么为什么不只存储 lambda 的副本呢?
相反,如果您存储的是std::function<void()>
或类似的东西,则不是对 lambda 的引用。 这是一个类型纠删节对象,它包装了一个 lambda 的副本。 在std::function<void()>
超出范围后存储对它的引用将是一个坏主意,因为它不是无状态的,并且当您尝试调用它时会关闭并读取垃圾内存。
可能不会完全填写您的答案,但看看 Herb Sutter 如何用 lambda 解决方案解决类似的 RAII。另请参阅此 SO 问题
template <class T> class locker {
private:
mutable T m_t; // Copies the lambda here.
mutable std::mutex m_m;
public:
locker( T t = T{} ) : m_t(t) {}
template <typename F>
auto operator()(F f) const -> decltype(f(m_t)) {
std::lock_guard<mutex> _{m_m};
return f(t);
}
};
// usage
locker<std::string> s;
s([](string &s) {
s += "foobar";
s += "barfoo";
});
关于此示例的重要部分是复制了 Lambda。您不应该保留对 lambda 的引用,因为函数本身将位于程序的只读部分中。lambda 保存的唯一数据是函数指针及其捕获。如果您确实有捕获,则取决于 lambda 的范围,如果超出范围,您将访问内存,该内存已经释放。
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 释放错误后堆使用
- G锁定铸造到基础上会释放模拟行为
- 在将变量声明为引用时,堆在释放后使用
- 在调用FreeLibrary后,释放动态链接到具有相同版本的CRT堆的DLL的内存
- 为什么擦除方法会影响结束方法
- 内联如何影响模块接口中的成员函数
- 正在理解智能指针,但出现错误:未分配正在释放的指针
- C++双重释放或损坏(out)
- 如何在c++中释放内存
- 为什么返回类型的'const'限定符对标有 __forceinline/内联的函数没有影响?
- 使用全局声明的向量时,C++双重释放错误/损坏
- 在容量内调整矢量大小时的性能影响
- 重载运算符的范围是什么?它是否会影响作为类成员的集合的插入函数?
- 为什么这个 std::queue/指向结构的指针列表直到 List.Size() == 0 才释放内存?
- 为什么瓦尔格林德在不释放恶意内存后没有报告任何问题?
- 调用析构函数以释放动态分配的内存
- 在函数范围内在堆栈上分配的数组在离开函数时是否总是被释放?
- COM :是否可以查看是否存在对我的某个 COM 对象的进程外引用?我可以释放它吗?
- C++11 λ 本身是否受 RAII 自动释放的影响