关于C++的lambda是函数还是对象,这其实不是一个一概而论的问题。
你所需要的网站建设服务,我们均能行业靠前的水平为你提供.标准是产品质量的保证,主要从事网站设计、做网站、企业网站建设、手机网站制作设计、网页设计、成都品牌网站建设、网页制作、做网站、建网站。创新互联公司拥有实力坚强的技术研发团队及素养的视觉设计专才。
先说结论:
首先,很多C++程序员从lambda 用法上反推容易发现是对象,因为lambda可以捕获!这是函数做不到的。的确,比如:
int n = 100;
auto foo = [n](int a) {
return a > n;
};
cout<< foo(99);
如果编译器要实现foo,大致类比这种写法(可能真实的实现细节不是这样,但思路类似)∶
struct Foo {
Foo(int i) {n=i;}
bool operator()(int a) {
return a > n;
}
private:
int n;
};
...
int n = 100;
Foo foo(n);
cout<< foo(99);
如果是引用捕获了变量,那么struct内有一个指针成员持有被引用捕获的变量的地址。
比如:
setns = {100, 200, 300};
auto foo = [&ns](int a) {
return ns.find(a);
};
cout<< foo(99);
大致等价于:
struct Foo {
Foo(set* p) {p_ns = p;}
bool operator()(int a) {
auto &ns = *p-ns;
return ns.find(a);
}
private:
set* p_ns;
};
...
setns = {100, 200, 300};
Foo foo(&ns);
cout<< foo(99);
在没有捕获任何东西的时候,lambda其实是等价于普通的函数的!可以用Linux C中函数pthread_create()来验证!它只能接收一个参数是void*,返回值也是void*的回调函数。
神奇的是,无参的lambda也可以被pthread_create()使用!
#include
#include
using namespace std;
struct A {
void* operator()(void*) {
cout<<"xxxx"<return nullptr;
}
};
int main() {
A a;
a(NULL);
pthread_t t;
//pthread_create(&t, NULL, a, NULL); // 编译失败
auto cb = [](void*)->void* {
cout<<"xxxx"<return nullptr;
};
pthread_create(&t, NULL, cb, NULL); // 编译通过
pthread_join(t, NULL);
return 0;
}
上面代码还可以再改一下,让cb去捕获一个变量, 比如:
auto cb = [&](void*)->void* {
cout<<"xxxx"<return nullptr;
};
pthread_create(&t, NULL, cb, NULL);
这时,给pthread_create()传入cb同样会编译失败!错误信息:
cb.cpp: In function ‘int main()’:
cb.cpp:23:30: error: cannot convert ‘main()::’ to ‘void* (*)(void*)’
23 | pthread_create(&t, NULL, cb, NULL);
| ^~
| |
| main()::
In file included from /usr/include/x86_64-linux-gnu/c++/9/bits/gthr-default.h:35,
from /usr/include/x86_64-linux-gnu/c++/9/bits/gthr.h:148,
from /usr/include/c++/9/ext/atomicity.h:35,
from /usr/include/c++/9/bits/ios_base.h:39,
from /usr/include/c++/9/ios:42,
from /usr/include/c++/9/ostream:38,
from /usr/include/c++/9/iostream:39,
from cb.cpp:1:
/usr/include/pthread.h:200:15: note: initializing argument 3 of ‘int pthread_create(pthread_t*, const pthread_attr_t*, void* (*)(void*), void*)’
200 | void *(*__start_routine) (void *),
| ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
这其实也不难理解,C++在lambda的设计上也贯彻着零开销 (Zero Overhead)原则,也就是C++不在性能上干多余的事,显然函数比对象开销更小。所以即使同为lambda,在有无捕获的时候,其底层实现其实是截然不同的!
当前标题:C++的lambda是函数还是对象?
网页URL:http://www.shufengxianlan.com/qtweb/news6/547156.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联