C ++中的lambda类型 [英] Type of lambdas in C++

查看:98
本文介绍了C ++中的lambda类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试用C ++学习lambda,但是偶然发现了一些我不太了解的东西.

I am trying to learn lambdas in C++, but stumbled on something I can't quite understand.

这是代码:

#include <iostream>

typedef double Func(double); 

double applyFunc(Func f, double x)
{
    return f(x);
}

int main()
{
    std::cout << applyFunc([](double x) {return x + 1;}, 3) << std::endl;
}

现在这可以正常工作(打印"4"),即所使用的lambda表达式的类型恰好是double (*)(double).

Now this works just fine (prints "4"), i.e. type of the lambda expression used is exactly double (*)(double).

但是如果我在lambda表达式中添加闭包,例如:

But if I add closure to the lambda expression, like:

int main()
{
    int n = 5;
    std::cout << applyFunc([n](double x) {return x + n;}, 3) << std::endl;
}

然后我从编译器中得到一个错误:

Then I get an error from the compiler:

In function ‘int main()’:
error: cannot convert ‘main()::__lambda0’ to ‘double (*)(double)’ for argument ‘1’ to ‘double applyFunc(double (*)(double), double)’
  3) << std::endl;
   ^

我不明白为什么会这样.我的意思是,从applyFunc()的角度来看,它仍然收到指向带有double参数并返回double的函数的指针,并且它不知道我们从上下文中使用了变量'n',因此类型的lambda表达式应该与第一个示例中的相同,对吧?

And I don't understand why is that. I mean, from the point of view of applyFunc() it still receives a pointer to a function taking double argument and returning double, and it doesn't know that we used variable 'n' from context, so the type of lambda expression should be the same, as in the first example, right?

非常感谢您的帮助,谢谢!

I would very appreciate help, thank you in advance!

推荐答案

只有在没有捕获的情况下,lambda才能转换为函数指针,我们可以通过转至标准草案5.1.2 Lambda表达式表示(强调我的):

A lambda is convertable to a function pointer only if it does not have a capture, we can see this by going to the draft standard section 5.1.2 Lambda expressions which says (emphasis mine):

没有lambda捕获的lambda表达式的关闭类型具有一个 公共非虚拟非显式const 指向指针的转换函数 功能,其参数和返回类型与闭包相同 类型的函数调用运算符.此转换返回的值 函数应是被调用时具有以下功能的函数的地址 与调用闭包类型的函数调用运算符的效果相同.

The closure type for a lambda-expression with no lambda-capture has a public non-virtual non-explicit const conversion function to pointer to function having the same parameter and return types as the closure type’s function call operator. The value returned by this conversion function shall be the address of a function that, when invoked, has the same effect as invoking the closure type’s function call operator.

这是不依赖于此转换的替代解决方案:

This is an alternative solution which does not rely on this conversion:

template <typename Callable>
double applyFunc(Callable f, double x)
{
    return f(x);
}

更新

如果您对使用std::function和模板之间的区别感兴趣,则应阅读 std :: function vs template .那里有很多好的答案,还有很多值得深思的地方.

If you are interested in the difference between using std::function and templates then you should read std::function vs template. There are many good answers there and a lot of food for thought.

这篇关于C ++中的lambda类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆