c++ - 如何将函数转换为 lambda 函数
问题描述
我有功能:
FARPROC PUDSClass::getFunction(LPSTR szName)
{
if(handleDLL == NULL)
{
return NULL;
}
return GetProcAddress(handleDLL, szName);
}
我正在尝试将其重写为 lambda 函数。
FARPROC lambda_decToStrHex = [&](LPSTR szName)
{
if (handleDLL == NULL)
{
return NULL;
}
return GetProcAddress(handleDLL, szName);
};
但我得到不一致类型“int”和“int(attribute(stdcall)*)()”的错误。
如果我这样写,它可以正常工作:
auto getFunction = [&](LPSTR szName)
{
return GetProcAddress(handleDLL, szName);
};
据我了解,lambda 无法处理返回 NULL 或 GetProcAddress(),但为什么普通函数可以这样做呢?
解决方案
FARPROC lambda_decToStrHex = ...;
这将创建一个变量lambda_decToStrHex
,它的类型是FARPROC
,根据文档,它被定义为
int (FAR WINAPI * FARPROC) ()
它是一个返回 int 且不接受参数的函数。这根本与您的 lambda 类型不匹配。
如果有的话,您需要一个 lambda 可以衰减到的正确类型的函数指针,一个接受 C 字符串并返回FARPROC
指针的函数(简而言之:指向函数返回函数指针的指针):
FARPROC (*lambda_decToStrHex)(LPSTR) = ...;
仅:您的lambda不能衰减为函数指针,因为它具有非空闭包:
... = [&](LPSTR name) { /* ... */ };
// ^ ^ uses dllHandle, which thus gets part of closure
所以剩下的就是将 lambda 分配给你的 lambda 类型的变量,你可以通过auto
.
编辑return NULL;
::
'Lambda' 在这里是一个红鲱鱼,它不是 lambda 的问题,而是任何推导出返回类型 ( auto f() { ... }
) 的函数。NULL
通常定义为(void*)0
, (但看起来也不同),因此在(在本例中)lambda 的两个退出点处会获得两种不同的返回类型 (void*
和)。FARPROC
现在应该推导出哪种返回类型?
一开始,你根本不应该再使用NULL
它,它是一个来自 C的宏,而 C++ 提供了一个关键字:nullptr
. 仅仅,它不能解决问题,因为它有自己的类型 ( std::nullptr_t
),它仍然不同于FARPROC
. 然后演员可以解决问题(实际上也可以与宏一起使用):
return static_cast<FARPROC>(nullptr);
现在两个出口点都有相同的返回类型,我们很好。尾随返回类型实现相同:
[&](LPSTR) -> FARPROC { ... }
nullptr
自动衰减到正确的指针类型(所以你不需要强制转换);NULL
但是,没有强制转换并且取决于定义方式的宏可以(但不必)失败。
另一种解决方案是一个单一的、定义明确的退出点:
[&](LPSTR)
{
FARPROC function = nullptr;
if(dllHandle)
function = get();
return function;
}
那为什么它可以与正常功能一起使用?好吧,您明确指定了返回类型 ( FARPROC f(...)
),这相当于有一个尾随返回类型。此外,它编译的事实和错误消息:
"int" and "int (attribute(stdcall)*)()"
^^^
揭示您的编译器显然NULL
在没有强制转换的情况下定义void*
:
#define NULL 0
或类似的 - 并且0
文字也衰减为空指针......
推荐阅读
- bash - 将数组传递给 GNU Parallel 以替换 for 循环
- webpack - Aurelia CLI 使用 Webpack 和“脚本加载器”的问题
- netbeans - 列出 NetBeans 8.2 maven java 非 Web 应用项目中的 NPM 库
- html - Safari 和 CSS 列的问题
- node.js - Chrome Node DevTools Inspector 停止列出文件
- node.js - 我们可以在团队中使用“npm link”命令吗?
- c++ - C++模板类,基于类型名改变类方法的行为
- html - 我应该如何将此 div 内的文本移动到底部中心?
- python - 如何在网络分析中将主要社区标记到节点
- ios - Xcode 9.4 无法打开文件“my_app”,因为您无权查看它