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

  发布时间:2025-11-04 10:40:41   作者:玩站小弟   我要评论
关于C++的lambda是函数还是对象,这其实不是一个一概而论的问题。 先说结论: 对于有捕获的lambda,其等价于对象。 对于没有任何捕获的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内有一个指针成员持有被引用捕获的函数还对变量的地址。

比如:

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,在有无捕获的时候,其底层实现其实是截然不同的!

b2b供应网
  • Tag:

相关文章

  • 深入了解live2d电脑教程(学习live2d电脑教程的关键技巧与方法)

    摘要:在当今的数字艺术领域中,live2d成为了越来越受欢迎的技术。它以其独特的二维卡通人物动态表现能力而备受推崇。然而,要掌握live2d并不容易,特别是对于初学者来说。本文将介绍一些...
    2025-11-04
  • 什么叫炒米?域名交易市场的术语你知道吗?

    相信不少小白都遇到过这样的问题,加入米友群后却看不到群内大佬们在说些什么?每次说起行业的术语就开始迷迷糊糊,如:什么叫炒米、煮米、收米?PUSH是什么意思?今天小聚就带大家来了解一些熟悉又陌生的域名行
    2025-11-04
  • 如何在 Python 中使用 DateTime

    所有数据在开始时都会自动分配一个“DOB”(出生日期)。因此,在某些时候处理数据时不可避免地会遇到日期和时间数据。本教程将带您了解 Python 中的 datetime 模块以及使用一些外围库,如pa
    2025-11-04
  • 可以在其他域名服务平台发布一口价域名吗?

    随着域名市场大热,二手域名的交易量也在不断提升。在众多域名交易方式中,一口价域名由于其本身公开透明的价格、快捷速度的交易模式受到买卖双方的喜欢。在此契机下,很多域名交易平台都推出了“一口价”服务,那么
    2025-11-04
  • 电脑加密显示参数错误的原因及解决方法(深入分析加密显示参数错误,保护个人信息安全)

    摘要:在使用电脑进行文件加密或者保护个人隐私时,我们有时会遇到加密显示参数错误的问题。这个问题可能会导致我们无法正确加密或保护文件,进而造成个人信息泄露的风险。本文将深入分析加密显示参数...
    2025-11-04
  • 在聚名网出售一口价域名,具体流程如何?

    在域名交易市场,一口价域名交易因为方便省时、价格透明、省时省力等特点成为米农们首选的交易方式。近期,就有朋友表示想在聚名网出售一口价域名,咨询具体流程,该怎么操作,下面小编就来详细介绍一下。在聚名网出
    2025-11-04

最新评论