捕获捕获本地临时性的lambda函数
Catching lambda functions capturing local temporaries
我最近在我们的代码库中发现了几个Lambda,它们大部分时间都能工作,但依赖于未定义的行为。这里有一个例子:
#include <iostream>
#include <thread>
std::thread thread;
void foo(int bar)
{
thread = std::thread([&]() { std::cout << bar << std::endl; });
}
int main(int argc, char* argv[])
{
foo(5);
thread.join();
}
问题是具有局部作用域(bar(的变量通过引用捕获,并在以后访问。奇怪的是,我们的编译器(GCC、Clang、MSVC(默认情况下都没有对此发出警告,即使它应该像"警告:返回本地临时对象的地址"一样容易被捕获。有没有办法让上述编译器对此发出警告?
这件事最近也引起了我的注意。我意识到我是通过引用bloomin'来捕获函数args的。
在这种情况下,我很想得到关于这一点的警告,但我怀疑我们没有得到警告的原因是,在许多情况下,捕获没有错。只要你立即执行lambda,你就安全了。只有当您存储它以供以后使用时(包括在工作线程中(,您才可能出现问题。
要么是编译器还不够聪明,要么是他们的作者决定不对此发出警告。
不管是什么情况,我不知道有任何主流编译器会对您的代码发出警告。所以你只需要非常小心。
您没有返回临时变量的地址。传递临时变量的引用是可以的。当然,当您通过引用线程传递变量时,如果最初传递临时变量的源函数已过期,则可能会导致意外结果。
但是,编译器并不关心线程的创建和线程顺序。因为人们可能会使用自己的线程库而不是std::thread
。从编译器的角度来看,它只是寻找语言结构的有效性,而[&](...){}
是一个有效的结构。
换句话说,编译器并没有办法捕捉到这个(实际上有用的(警告。遗憾的是,这是程序员的责任。您可以将argv
复制到std::string
对象并按值传递。
相关文章:
- C++Boost Asio Pool线程,带有lambda函数和传递引用变量
- 如何建立使用模板函数的lambda函数的尾部返回类型
- 我可以将调用类的"this"传递给 lambda 函数吗?
- 两组使用lambda函数的大括号
- 尝试将lambda函数放在队列中时出现一般分配器错误(可能是与unique_ptr有关的错误)
- 我可以在这里替换什么,因为我不能在 C# 中使用隐式变量的 lambda 函数?
- 为什么我不能在 constexpr lambda 函数中使用 std::tuple
- C++:Lambda 函数指针转换的用例是什么?
- 将 lambda 函数作为参数传递C++
- 如何将 lambda 函数作为参数发送到另一个函数
- 传递 lambda 函数的权衡是什么?
- 如何使用类模拟 C++11 中的 lambda 函数和闭包?
- 不是 lambda 函数中的常量表达式
- 如何使用可变参数数重载 lambda 函数?
- 如何通过指针传递lambda函数?
- 使用带有 lambda 函数指针的模板
- openmp c++ 中并行块内 lambda 函数的奇怪行为
- C++ 中 Lambda 函数中的溢出
- 将数组传递到 lambda 函数中
- lambda 函数未显示正确的结果