Important update: Apparently I drew the wrong conclusion when I asked this question. Thanks to the responses I found out the lambda function [=]()
does work fine in a multithreaded scenario. My apologies for posing this confusing question. Please vote to close, as it was a non-issue.
In our company we've written a library function to call a function asynchronously in a separate thread. It works using a combination of inheritance and template magic. The client code looks as follows:
DemoThread thread;
std::string stringToPassByValue = "The string to pass by value";
AsyncCall(thread, &DemoThread::SomeFunction, stringToPassByValue);
Since the introduction of lambda functions I'd like to use it in combination with lambda functions. I'd like to write the following client code:
DemoThread thread;
std::string stringToPassByValue = "The string to pass by value";
AsyncCall(thread, [=]()
{
const std::string someCopy = stringToPassByValue;
});
Update: contrary to what I first believed when asking this question, this code works fine.
Now, with the Visual C++ 2010 this code doesn't work. What happens is that the stringToPassByValue
is not copied. Instead the "capture by value" feature passes the data by reference. The result is that if the function is executed after stringToPassByValue
has gone out of scope, the application crashes as its destructor is called already.
So I wonder: is it possible to pass data to a lambda function as a copy?
Note: One possible solution would be to modify our framework to pass the data in the lambda parameter declaration list, as follows:
DemoThread thread;
std::string stringToPassByValue = "The string to pass by value";
AsyncCall(thread, [=](const std::string stringPassedByValue)
{
const std::string someCopy = stringPassedByValue;
}
, stringToPassByValue);
However, this solution is so verbose that our original function pointer solution is both shorter and easier to read.
Update: The full implementation of AsyncCall
is too big to post here. In short, what happens is that the AsyncCall
template function instantiates a template class holding the lambda function. This class is derived from a base class that contains开发者_运维技巧 a virtual Execute()
function, and upon an AsyncCall()
call, the function call class is put on a call queue. A different thread then executes the queued calls by calling the virtual Execute()
function, which is polymorphically dispatched to the template class which then executes the lambda function.
精彩评论