Is it possible to use the new lambda expressions in Visual C++ 2010 as CLR event handlers? I've tried the following code:
SomeEvent += gcnew EventHandler(
[] (Object^ sender, EventArgs^ e) {
// code here
}
);
It results in the following error message:
error C3364: 'System::EventHandler' : invalid argument for delegate constructor; delegate target needs to be a pointer to a member function
Am I attempting the impossible, or is simply my syntax wrong?
The following is my solution that allows one to wrap lambdas (as well as any function objects - i.e. anything on which
operator()
can be called) into delegates. It has some limits - specifically, it doesn't support delegates with tracking reference parameters (%
in C++/CLI,ref
/out
in C#); and it has an upper limit on the number of parameters the delegate can take (because VC++2010 doesn't suppport vararg templates) - though the code can be trivially adjusted to support up to as many as you want.Sample usage:
While this technically does what you want, the practical applications are somewhat limited due to the fact that C++0x lambdas are expanded into plain classes, not
ref
orvalue
ones. Since plain classes cannot contain managed types in C++/CLI (i.e. no members of object handle type, no members of tracking reference type, and no members ofvalue class
type), this means that lambdas cannot capture any variables of those types, either. There is no workaround I'm aware of for tracking references. Forvalue class
, you can take an unmanaged pointer to it (pin_ptr
if needed), and capture that.For object handles, you can store them in
gcroot<T>
, and capture that - but there are severe performance implications - in my tests, accessing a member viagcroot<T>
is about 40x times slower than doing it using a plain object handle. It's actually not much in absolute measure for a single call, but for something that is called repeatedly in a loop - say, most LINQ algorithms - it would be a killer. But note that this only applies when you need to capture a handle in the lambda! If you just use it to write a predicate inline, or to update a counter, it'll work just fine.No can do, the C++/CLI compiler didn't get updated to accept the lambda syntax. Fairly ironic btw given the head-start that managed code had.
This page has a few examples of lambdas for C++:
http://msdn.microsoft.com/en-us/library/dd293608%28v=VS.100%29.aspx
Microsoft VS2010 C++ improvements look like they actually implement C++0x lambda spec. As such they are purely unmanaged and are of type
lambda
.There is nothing in the Microsoft documentation that hints at possibility of using C++ lambdas as CLR lambdas. At this stage I have to say that you cannot use C++ lambdas as handlers for managed delegates.