C++ lambda函数何时捕获变量

enyaitl3  于 2022-12-01  发布在  其他
关注(0)|答案(1)|浏览(299)

以下代码块通过lambda表达式启动线程。此lambda表达式通过引用捕获局部变量"testVar"。在线程函数执行时,该局部变量超出范围,线程函数将无法访问正确值。通过将捕获子句中的"&"更改为"=",对通过复制捕获进行了简要测试。for循环似乎打印了正确的值。我的问题是捕获发生在什么时候?是在创建lambda函数时还是在执行线程时发生?在后一种情况下,通过复制进行捕获不应该产生正确的结果。

#include <iostream>
#include <string>
#include <vector>
#include <thread>

int main()
{
  std::thread myThread;
  {
      std::vector<int> testVar(10, 128);
      std::cout<<"Trying to create thread"<<std::endl;
      myThread = std::thread([&](){std::this_thread::sleep_for(std::chrono::seconds(3));for(int i=0; i<10; i++){std::cout<<testVar[i]<<std::endl;}});
  }
  myThread.join();
}

按引用捕获将产生以下结果
正在尝试创建线程1580344384 21851 1580269584 21851 128 128 128 128 128 128
通过拷贝捕获会产生以下结果
正在尝试创建线程128 128 128 128 128 128 128 128 128 128 128 128

xxhby3vn

xxhby3vn1#

lambda是一个expression,它的值实际上是一个functional object。它在表达式求值时捕获变量,如果你把它放在同一个地方,它和任何其他表达式求值的同时发生。也就是说,它会发生在program order中。
如果我们将代码扩展一点,...

std::vector<int> testVar(10, 128);
std::cout<<"Creating the thread function";
auto thread_function = [&](){
    std::this_thread::sleep_for(std::chrono::seconds(3));
    for(int i=0; i<10; i++){
        std::cout<<testVar[i]<<std::endl;
    }
};
std::cout<<"Trying to create thread"<<std::endl;
myThread = std::thread(thread_function);

......然后对lambda求值,捕获testVar引用,* 在 * 程序输出“Creating the thread function”之后,* 在 * 它输出“Trying to create thread”之前。显然,这一切都发生在创建线程对象之前。

相关问题