[英]C++ lambda expressions - How does the compiler interpret them?
I just starter learning the new features in C++ 11. I was reading about lambdas in C++ Primer (Stanley Lippman) and was experimenting with them. 我刚开始学习C ++ 11中的新功能。我正在阅读C ++ Primer(Stanley Lippman)中的lambdas并正在尝试它们。
I tried the following pieces of code: 我尝试了以下代码:
auto func() -> int (*) (){
//int c=0;
return []()-> int {return 0;};
}
int main(){
auto p = func();
}
This code compiled fine. 这段代码编译得很好。 So I guess lambdas without any captures are just generated as normal functions by the compiler and we can use a normal function pointer to them. 所以我猜没有任何捕获的lambdas只是由编译器生成为普通函数,我们可以使用它们的普通函数指针。
Now I changed the code to use captures: 现在我更改了代码以使用捕获:
auto func() -> int (*) (){
int c=0;
return [=]()-> int {return c;};
}
int main(){
auto p = func();
}
But this failed to compile. 但这无法编译。 I got the following compilation error while using g++: 使用g ++时出现以下编译错误:
main.cpp: In function ‘int (* func())()’:
main.cpp:6:31: error: cannot convert ‘func()::__lambda0’ to ‘int (*)()’ in return
return [=]()-> int {return c;};
From the error I can understand that it is not a normal function that is generated and it might probably be a class with an overloaded call-operator. 从错误中我可以理解,它不是生成的普通函数,它可能是一个带有重载调用操作符的类。 Or is it something else? 或者是别的什么?
My questions : How does the compiler handle lambdas internally? 我的问题:编译器如何在内部处理lambdas? How should I pass around lambdas that use captures ie what should be the return value from func()? 我应该如何传递使用捕获的lambda,即func()的返回值应该是什么? I cant currently think of a use case where I would need to use lambdas like this but I just want to understand more about them. 我目前无法想到一个用例,我需要使用这样的lambdas,但我只是想了解更多关于它们的信息。 Please help. 请帮忙。
Thanks. 谢谢。
All lambdas are function objects with implementation defined type called closure type with a operator()
member. 所有lambda都是具有实现定义类型的函数对象,称为闭包类型 ,带有operator()
成员。 Every lambda expression has it's own unique closure type, too. 每个lambda表达式都有自己独特的闭包类型。
Lambdas without a capture can be converted to a function pointer. 没有捕获的Lambda可以转换为函数指针。 Whether or not compiler generates a normal function behind the scenes is an internal detail and shouldn't matter to you. 编译器是否在幕后生成正常函数是一个内部细节,对您来说无关紧要。
It's not possible to return a lambda that's defined inside a function. 无法返回在函数内定义的lambda。 There are few things that prevent this - you don't know the name of a type of lambda expression, you can't use a lambda expression inside a decltype
and as already said, two lambda expressions (even if lexically identical) have different types. 很少有东西阻止这种情况 - 你不知道一种lambda表达式的名称,你不能在decltype
使用lambda表达式,正如已经说过的,两个lambda表达式(即使词法相同)有不同的类型。
What you can do is use std::function
: 你可以做的是使用std::function
:
std::function<int()> func()
{
int i = 0;
return [=]()-> int {return i;};
}
This way works with captures, too. 这种方式也适用于捕获。
Or something like this: 或类似的东西:
auto f = []{ return 0; };
auto func() -> decltype(f)
{
return f;
}
EDIT: The upcoming C++1y standard (more specifically, return type deduction), however, will allow you to do this: 编辑:然而,即将推出的C ++ 1y标准(更具体地说,返回类型扣除)将允许您这样做:
auto func()
{
int i = 42;
return [=]{ return i; };
}
Compiler is free to decide how to generate the type of a lambda function. 编译器可以自由决定如何生成lambda函数的类型。 It generates a function object that means you can invoke it by ()
. 它生成一个函数对象,这意味着您可以通过()
调用它。 But the type can be different in various situations. 但是在各种情况下类型可能不同。 Every single lambda can has a unique type. 每一个lambda都可以有一个独特的类型。 A simple lambda (doesn't capture anything) can be stored in a pointer to function. 一个简单的lambda(不捕获任何东西)可以存储在指向函数的指针中。
In C++11, to wrap a lambda which captures data, you can use std::function
: 在C ++ 11中,要包装捕获数据的lambda,可以使用std::function
:
auto func() -> std::function<int()> {
int c = 0;
return [=]()-> int {return c;};
}
In C++14, it has function return type deduction , let the compile handle it: 在C ++ 14中,它有函数返回类型推导 ,让编译处理它:
auto func() {
int c = 0;
return [=]()-> int {return c;};
}
A function cannot return a lambda function itself. 函数本身不能返回lambda函数。 If you write: 如果你写:
auto func() -> int () {
int c=0;
return [=]()-> int {return c;};
}
Then GCC complains: 然后海湾合作委员会抱怨:
lambda.cpp:3:21: error: function return type cannot be function
auto func() -> int (){
So the solution is to wrap the return object into a std::function
: 所以解决方案是将返回对象包装到std::function
:
#include <functional>
auto func() -> std::function<int ()> {
int c=0;
return [=]()-> int {return c;};
}
int main(){
auto p = func();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.