您好,登錄后才能下訂單哦!
這篇“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使用實例分析”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。