ddzzBowen
ddzzBowen

Reputation: 11

When does C++ lambda function captures the variables

The following code block launches a thread via a lambda expression. This lambda expression captures a local variable "testVar" by reference. By the time the thread function executes that local variable goes out of scope and the thread function will not be able to access the correction values. Briefly tested capturing by copy by changing "&" to "=" in the capture clause. The for loop seems to print the correct values. My question is when does the capture happen? Does it happen when the lambda function is created or when the thread gets executed. In the latter case, capturing by copy should not produce the right results.

#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();
}

Capturing by reference produces the following result

Trying to create thread 1580344384 21851 1580269584 21851 128 128 128 128 128 128

Capturing by copy produces the following result

Trying to create thread 128 128 128 128 128 128 128 128 128 128

Upvotes: 1

Views: 1453

Answers (1)

Solomon Slow
Solomon Slow

Reputation: 27190

A lambda is an expression whose value effectively is a functional object. It captures variables when the expression is evaluated, and that happens at the same time as any other expression would be evaluated if you put it in the same place. That is to say, it would happen in program order.

If we expand your code a bit,...

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);

...Then the lambda would be evaluated, and the testVar reference would be captured, after the program printed "Creating the thread function," and before it printed "Trying to create thread." Clearly, that all happens before the thread object is created.

Upvotes: 1

Related Questions