如何将函数转换为Lambda函数

时间:2019-08-29 10:05:10

标签: c++ function 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(),但是为什么普通函数可以这样做?

2 个答案:

答案 0 :(得分:3)

FARPROC lambda_decToStrHex = ...;

这将创建一个变量lambda_decToStrHex,其类型为FARPROC,根据documentation,其定义为

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(但外观也可能有所不同),因此在两个出口处您将获得两种不同的返回类型(void*FARPROC) (在这种情况下)lambda。现在应该推算哪种返回类型?

起初,您完全不应该使用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的文字也将衰减为空指针...

答案 1 :(得分:2)

由于您在常规函数中指定了返回类型FARPROC,因此NULL0,即int类型)将隐式转换为FARPROC类型(就是int (attribute(stdcall)*)())。

您可以使用->通过lambda指定返回类型:

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