成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

C++的lambda是函數還是對象?

開發 后端
C++在lambda的設計上也貫徹著零開銷 (Zero Overhead)原則,也就是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()使用!

#include <iostream>
#include <pthread.h>
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語言與C++編程
相關推薦

2020-10-16 06:40:25

C++匿名函數

2012-07-03 10:48:43

C++Lambda

2010-01-25 09:50:58

C++函數對象

2010-02-02 13:15:00

C++ lambda函

2009-04-14 14:53:06

C++Lambda函數多線程

2010-01-27 10:13:22

C++類對象

2024-12-17 12:00:00

C++對象模型

2010-02-06 09:31:42

C++函數對象

2011-07-20 13:40:09

拷貝構造函數

2010-01-27 17:16:52

C++構造函數

2010-01-26 10:42:26

C++函數

2010-01-19 13:43:59

C++函數

2022-09-19 14:12:27

C++Lambda表達式

2023-11-29 09:47:11

C++對象

2025-04-02 03:11:00

Python函數C++

2023-12-04 10:57:52

函數C++

2011-06-17 16:09:04

freadfwrite

2024-11-27 08:26:00

C++模板靜態

2023-03-23 18:40:18

Lambda編程C++

2023-11-02 08:25:58

C++Lambda
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美成视频 | 亚洲3p| 日韩精品视频一区二区三区 | 亚洲国产日韩欧美 | 伊人久久大香线 | 久久91| 夜夜夜夜草 | 日韩91| 免费的av网站 | 国产精品一区久久久 | 看亚洲a级一级毛片 | 国产高清自拍视频在线观看 | 99久久久无码国产精品 | 日韩最新网站 | 亚洲精品9999 | 免费看一区二区三区 | 羞羞涩涩在线观看 | 国产精品一区二区不卡 | 欧美精品一区免费 | 国产午夜精品久久久 | 亚洲免费婷婷 | 综合久久色 | 国产午夜视频 | 午夜精品一区二区三区在线视 | 久久久久久久久91 | 久久精品中文字幕 | 99国产精品久久久久 | 欧美一级黄色网 | 毛片高清 | 一级做a毛片 | 黑人巨大精品欧美一区二区免费 | 亚洲一区 中文字幕 | 免费午夜视频 | 成人精品毛片国产亚洲av十九禁 | 玖操| 欧美精品一区二区三区在线播放 | 鸳鸯谱在线观看高清 | 亚洲一区成人 | 久久久久久网 | 欧美一区二区在线免费观看 | 欧美中文字幕一区二区三区 |