Lambda 表达式作为 Visual C++ 中的 CLR (.NET) 委托/事件处理程序; 2010年
是否可以使用 Visual C++ 2010 中的新 lambda 表达式作为 CLR 事件处理程序?我尝试过以下代码:
SomeEvent += gcnew EventHandler(
[] (Object^ sender, EventArgs^ e) {
// code here
}
);
它会导致以下错误消息:
错误 C3364:“System::EventHandler”:委托构造函数的参数无效;委托目标需要是指向成员函数的指针
我是否在尝试不可能的事情,或者只是我的语法错误?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
以下是我的解决方案,它允许将 lambda(以及任何函数对象 - 即可以调用
operator()
的任何对象)包装到委托中。它有一些限制 - 具体来说,它不支持带有跟踪引用参数的委托(C++/CLI 中的%
,C# 中的ref
/out
);并且它对委托可以采用的参数数量有上限(因为 VC++2010 不支持可变参数模板) - 尽管可以轻松调整代码以支持您想要的数量。示例用法:
虽然这在技术上可以满足您的需求,但由于 C++0x lambda 被扩展为普通类,而不是
ref
或value 的。由于普通类不能包含 C++/CLI 中的托管类型(即没有对象句柄类型的成员、没有跟踪引用类型的成员以及没有
值类
类型的成员),这意味着 lambda 无法捕获任何类型。这些类型的变量。据我所知,没有任何解决方法可以跟踪引用。对于值类
,您可以获取指向它的非托管指针(pin_ptr
如果需要),并捕获它。对于对象句柄,您可以将它们存储在
gcroot
中,并捕获它 - 但会产生严重的性能影响 - 在我的测试中,通过gcroot
访问成员> 比使用普通对象句柄慢大约 40 倍。实际上,对于单次调用而言,它的绝对值并不大,但对于在循环中重复调用的东西(例如,大多数 LINQ 算法)来说,这将是一个杀手。但请注意,这仅适用于您需要捕获 lambda 中的句柄时!如果您只是用它来编写内联谓词或更新计数器,那么它就可以正常工作。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.没办法,C++/CLI 编译器没有更新以接受 lambda 语法。顺便说一句,考虑到托管代码的领先优势,这相当讽刺。
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.
此页面有一些 C++ 的 lambda 示例:
http://msdn.microsoft.com/en-us/library/dd293608%28v=VS.100%29.aspx
Microsoft VS2010 C++ 改进看起来确实实现了 C++0x lambda 规范。因此,它们完全是非托管的,并且属于 lambda 类型。
Microsoft 文档中没有任何内容暗示可以将 C++ lambda 用作 CLR lambda。在这个阶段,我不得不说,您不能使用 C++ lambda 作为托管委托的处理程序。
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.