首页 > 解决方案 > 如何将函数转换为 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(),但为什么普通函数可以这样做呢?

标签: c++functionlambda

解决方案


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文字也衰减为空指针......


推荐阅读