论C++的lambda是函数还是对象

论C++的lambda是函数还是对象

先说结论:

对于有捕获的lambda,其等价于对象。

对于没有任何捕获的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内有一个指针成员持有被引用捕获的变量的地址。

比如:

set<int> ns = {100, 200, 300}; auto foo = [&ns](int a) {     return ns.find(a); }; cout<< foo(99);

大致等价于:

struct Foo {     Foo(set<int>* p) {p_ns = p;}     bool operator()(int a) {         auto &ns = *p-ns;         return ns.find(a);     } private:     set<int>* p_ns; }; ... set<int> ns = {100, 200, 300}; Foo foo(&ns); cout<< foo(99);

然而……这并不是全部!
在没有捕获任何东西的时候,lambda其实是等价于普通的函数的!可以用Linux C中函数pthread_create()来验证!它只能接收一个参数是void*,返回值也是void*的回调函数。

神奇的是,无参的lambda也可以被pthread_create()使用!

using namespace std; struct A {     void* operator()(void*) {         cout<<"xxxx"<<endl;         return nullptr;     } }; int main() {     A a;     a(NULL);     pthread_t t;     //pthread_create(&t, NULL, a, NULL); // 编译失败     auto cb = [](void*)->void* {         cout<<"xxxx"<<endl;         return nullptr;     };     pthread_create(&t, NULL, cb, NULL); // 编译通过     pthread_join(t, NULL);     return 0; }

上面代码还可以再改一下,让cb去捕获一个变量, 比如:

auto cb = [&](void*)->void* {         cout<<"xxxx"<<endl;         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()::<lambda(void*)>' to ‘void* (*)(void*)'    23 |     pthread_create(&t, NULL, cb, NULL);       |                              ^~       |                              |       |                              main()::<lambda(void*)> 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是函数还是对象的文章就介绍到这了,更多相关C++中的lambda内容请搜索易知道(ezd.cc)以前的文章或继续浏览下面的相关文章希望大家以后多多支持易知道(ezd.cc)!

推荐阅读

    excel怎么用乘法函数

    excel怎么用乘法函数,乘法,函数,哪个,excel乘法函数怎么用?1、首先用鼠标选中要计算的单元格。2、然后选中单元格后点击左上方工具栏的fx公

    excel中乘法函数是什么?

    excel中乘法函数是什么?,乘法,函数,什么,打开表格,在C1单元格中输入“=A1*B1”乘法公式。以此类推到多个单元。1、A1*B1=C1的Excel乘法公式

    标准差excel用什么函数?

    标准差excel用什么函数?,函数,标准,什么,在数据单元格的下方输入l标准差公式函数公式“=STDEVPA(C2:C6)”。按下回车,求出标准公差值。详细

    网页抓取电脑信息|电脑网页捕获

    网页抓取电脑信息|电脑网页捕获,,1. 电脑网页捕获可以使用抓包软件,推荐使用SmartSniff,关闭其它网络程序,点击SmartSniff启动捕获,再打开软件

    excel常用函数都有哪些?

    excel常用函数都有哪些?,函数,哪些,常用,1、SUM函数:SUM函数的作用是求和。函数公式为=sum()例如:统计一个单元格区域:=sum(A1:A10)  统计多个

    Python之可迭代对象、迭代器、生成器

    Python之可迭代对象、迭代器、生成器,迭代,生成器,一、概念描述可迭代对象就是可以迭代的对象,我们可以通过内置的iter函数获取其迭代器,可

    应用程序对象

    应用程序对象,,应用程序对象是一个应用程序级对象,用于在所有用户之间共享信息,并且在Web应用程序运行期间可以保存数据。 应用的性质: 方法