如何将函数转换为 lambda 函数

How to transform function to lambda function

本文关键字:函数 lambda 转换      更新时间:2023-10-16

我有函数:

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(属性(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)*)()"
^^^

揭示您的编译器显然定义了没有void*强制转换的NULL

#define NULL 0

或类似 –0字面也衰减为空指针......

>由于您在正常函数中指定了返回类型FARPROC,因此NULL(0,这是int类型(将隐式转换为FARPROC类型(int (attribute(stdcall)*)()(。

您可以使用使用->指定带有 lambda 的返回类型:

auto lambda_decToStrHex = [&](LPSTR szName) -> FARPROC
{
if (handleDLL == NULL)
{
return NULL;
}
return GetProcAddress(handleDLL, szName);
};