I'm in a situation in a multithreaded environment where I have a thread that receives data from a socket, and I want to send that data into a messaging queue.
For instance, something like this:
char buf[N];
size_t len = ::recv(buf, ...);
queue.send([buf,len] {
//stuff
});
But that won't work since buf
could go out of scope, or get overwritten by the next ::recv()
. Now I COULD copy it into a string
/std::vector
/whatever and pass THAT thing by value:
char buf[N];
size_t len = ::recv(buf, ...);
std::string my_data(buf, len);
queue.send([my_data](){ /* stuff */ });
But there I'm incurring an extra copy, right? Is there a way to get that same functionality without the extra overhead?
Much like functions can change the value of arguments passed by reference, we can also capture variables by reference to allow our lambda to affect the value of the argument. To capture a variable by reference, we prepend an ampersand ( & ) to the variable name in the capture.
Capture clause A lambda can introduce new variables in its body (in C++14), and it can also access, or capture, variables from the surrounding scope. A lambda begins with the capture clause. It specifies which variables are captured, and whether the capture is by value or by reference.
Lambda expression with value capture. Lambda expressions can capture of outer scope variables into a lambda function. The captured variables are stored in the closure object created for the lambda function.
Yes, you can. The Standard says that (5.1.2p21):
When the lambda-expression is evaluated, the entities that are captured by copy are used to direct-initialize each corresponding non-static data member of the resulting closure object. (For array members, the array elements are direct-initialized in increasing subscript order.)
which makes it clear that a lambda can capture an array by copy.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With