C++0x 是否支持 __stdcall 或 extern "C"不捕获任何 lambda?
昨天我在想是否可以利用C++0x lambda函数的便利性来为Windows API函数编写回调。
例如,如果我想使用 lambda 作为 EnumChildProc
与
EnumChildWindows
?类似于:
EnumChildWindows(hTrayWnd, CALLBACK [](HWND hWnd, LPARAM lParam) {
// ...
return static_cast<BOOL>(TRUE); // continue enumerating
}, reinterpret_cast<LPARAM>(&myData));
另一个用途是为 C 例程编写 extern "C"
回调。例如:
my_class *pRes = static_cast<my_class*>(bsearch(&key, myClassObjectsArr, myClassObjectsArr_size, sizeof(my_class), extern "C" [](const void *pV1, const void *pV2) {
const my_class& o1 = *static_cast<const my_class*>(pV1);
const my_class& o2 = *static_cast<const my_class*>(pV2);
int res;
// ...
return res;
}));
这可能吗?
我可以理解捕获变量的 lambda 永远不会与 C 兼容,但至少在我看来,capture-nothing lambda 可以兼容。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
没有捕获的 Lambda可以隐式转换指向函数的指针(通过闭包类型定义的非显式转换函数)。
FCD似乎没有指定该函数指针类型的函数类型具有什么语言链接,因此如果需要将此函数指针传递给C函数,则C++函数和C函数的调用约定需要相同。我相信在 Windows 上,情况确实如此。因此,您应该能够将 lambda 传递给
5.1.2/6
处的 Windows API 函数 FCD 措辞:我认为最终标准应该有一个注释,指出有一个到 C 链接函数指针和 C++ 链接函数指针的转换函数,因为到 C 函数指针的可转换性是此功能的目标之一。
Lambdas without a capture are implicitly convertible to a pointer to function (by a non-explicit conversion function defined by the closure type).
The FCD does not seem to specify what language linkage the function type of that function pointer type has, so if you need to pass this function pointer to C functions, the calling convention of C++ functions and C functions need to be the same. I believe that on Windows, that is the case though. So you should be able to pass the lambda to Windows API functions
FCD wording at
5.1.2/6
:I think the final Standard should have a note that says that there is a conversion function to both C linkage function pointers and C++ linkage function pointers, as convertibility to C function pointers is one of the goal of this functionality.
函数指针的语言链接源自无捕获 lambda 的转换,该转换未在 C++11 标准中指定,但已在 缺陷报告 1557 内容如下:
决议是语言链接应该是 C++:
我们可以在 C++14 标准草案中找到这种语言,因为状态是 DRWP ,这似乎不适用于 C++11。
The language linkage of the function pointer results from a conversion of a capture-less lambda was not specified in the C++11 standard but was addressed in defect report 1557 which says:
and the resolution was that the language linkage should be C++:
we can find this language in the draft C++14 standard, since the status is
DRWP
it seems like this does not apply to C++11.没有特别充分的理由表明这不应该扩展到捕获 lambda。它需要一些动态代码生成,但它不应该超出编译器编写者的智慧,并且它将使与旧 C API 的互操作变得更容易——不再需要通过无类型 void* 传递参数(这不是所有的) API 甚至提供)。
There's no particularly good reason that this shouldn't be extended to capturing lambdas. It requires some dynamic code generation, but it shouldn't be beyond the wit of compiler writers, and it would make interop with old C APIs orders of magnitude easier--no more need to pass parameters through untyped void*s (which not all APIs even offer).