C++開發(fā)EOS基礎(chǔ)指南:迭代器和Lambda表達(dá)式

讓我們來談?wù)劦鞲对铮且粋€(gè)非常有用的工具敷钾,在整個(gè)EOS代碼庫(kù)中大量使用枝哄。如果您來自JavaScript背景,您可能已經(jīng)熟悉迭代器闰非,就像它們用于循環(huán)一樣膘格。迭代器的關(guān)鍵概念是提供一種更好的方法來遍歷項(xiàng)集合。額外的好處是您可以為任何自定義類實(shí)現(xiàn)迭代器接口财松,使迭代器成為遍歷數(shù)據(jù)的通用方法。

// @url: https://repl.it/@MrToph/CPPBasics-Iterators
#include <iostream>
#include <vector>

using namespace std;

int main()
{
  vector<int> v{2, 3, 5, 8};
  // old way to iterate
  for (int i = 0; i < v.size(); i++)
  {
    cout << v[i] << "\n";
  }

  // using Iterators
  // begin() returns an iterator that points to the beginning of the vector
  // end() points to the end, can be compared using != operator
  // iterators are incremented by using the + operator thanks to operator-overloading
  for (vector<int>::iterator i = v.begin(); i != v.end(); i++)
  {
    // iterators are dereferenced by * like pointers
    // returns the element the iterator is currently pointing to
    cout << *i << "\n";
  }

  // auto keyword allows you to not write the type yourself
  // instead C++ infers it from the return type of v.begin
  for (auto i = v.begin(); i != v.end(); i++)
  {
    cout << *i << "\n";
  }

  // can use arithmetic to "jump" to certain elements
  int thirdElement = *(v.begin() + 2);
  cout << "Third: " << thirdElement << "\n";
  // end is the iterator that points to the "past-the-end" element
  // The past-the-end element is the theoretical element that would follow the last element in the vector.
  // It does not point to any element, and thus shall not be dereferenced.
  int lastElement = *(v.end() - 1);
  cout << "Last: " << lastElement << "\n";

  // do not go out of bounds by iterating past the end() iterator
  // the behavior is undefined
  // BAD: v.end() + 1, v.begin() + 10
}

在現(xiàn)代C++中纱控,迭代器是迭代元素集合(向量辆毡,列表,映射)的首選方式甜害。另外舶掖,auto關(guān)鍵字可以避免輸入word類型,但可能會(huì)導(dǎo)致代碼性能降低尔店。

Lambda表達(dá)式

使用迭代器眨攘,我們可以開始研究現(xiàn)代C++的函數(shù)式編程概念。標(biāo)準(zhǔn)庫(kù)中的許多函數(shù)采用由兩個(gè)迭代器(開始和結(jié)束)和匿名函數(shù)(lambda函數(shù))表示的一系列元素作為參數(shù)嚣州。然后將此匿名函數(shù)應(yīng)用于范圍內(nèi)的每個(gè)元素鲫售。它們被稱為匿名函數(shù),因?yàn)樗鼈儾皇墙壎ǖ阶兞扛秒龋撬鼈兪嵌踢壿媺K情竹,作為內(nèi)聯(lián)參數(shù)傳遞給更高階函數(shù)。通常匀哄,它們對(duì)于傳遞給它們的函數(shù)是唯一的秦效,因此不需要具有名稱(匿名)的整個(gè)開銷。

有了它涎嚼,我們可以實(shí)現(xiàn)類似于排序阱州,映射,過濾等的構(gòu)造法梯,這些構(gòu)造在JavaScript等語(yǔ)言中很容易實(shí)現(xiàn):

[1,2,3,4].map(x => x*x).filter(x => x % 2 === 1).sort((a,b) => b - a)

C++中的代碼并不簡(jiǎn)潔苔货,但結(jié)構(gòu)相同。來自std庫(kù)的許多函數(shù)式編程助手以半開間隔運(yùn)行,這意味著包括較低范圍蒲赂,排除較高范圍阱冶。

// @url: https://repl.it/@MrToph/CPPBasics-Lambdas
#include <iostream>
#include <vector>
// for sort, map, etc.
#include <algorithm>

using namespace std;

int main()
{
  vector<int> v{2, 1, 4, 3, 6, 5};
  // first two arguments are the range
  // v.begin() is included up until v.end() (excluded)
  // sorts ascending
  sort(v.begin(), v.end());

  // in C++, functions like sort mutate the container (in contrast to immutability and returning new arrays in other languages)
  for (auto i = v.begin(); i != v.end(); i++)
  {
    cout << *i << "\n";
  }

  // sort it again in descending order
  // third argument is a lambda function which is used as the comparison for the sort
  sort(v.begin(), v.end(), [](int a, int b) { return a > b; });

  // functional for_each, can also use auto for type
  for_each(v.begin(), v.end(), [](int a) { cout << a << "\n"; });

  vector<string> names{"Alice", "Bob", "Eve"};
  vector<string> greetings(names.size());

  // transform is like a map in JavaScript
  // it applies a function to each element of a container
  // and writes the result to (possibly the same) container
  // first two arguments are range to iterate over
  // third argument is the beginning of where to write to
  transform(names.begin(), names.end(), greetings.begin(), [](const string &name) {
    return "Hello " + name + "\n";
  });
  // filter greetings by length of greeting
  auto new_end = std::remove_if(greetings.begin(), greetings.end(), [](const string &g) {
    return g.size() > 10;
  });
  // iterate up to the new filtered length
  for_each(greetings.begin(), new_end, [](const string &g) { cout << g; });
  // alternatively, really erase the filtered out elements from vector
  // so greetings.end() is the same as new_end
  // greetings.erase(new_end, greetings.end());

  // let's find Bob
  string search_name = "Bob";
  // we can use the search_name variable defined outside of the lambda scope
  // notice the [&] instead of [] which means that we want to do "variable capturing"
  // i.e. make all local variables available to use in the lambda function
  auto bob = find_if(names.begin(), names.end(), [&](const string &name) {
    return name == search_name;
  });
  // find_if returns an iterator referncing the found object or the past-the-end iterator if nothing was found
  if (bob != names.end())
    cout << "Found name " << *bob << "\n";
}

匿名函數(shù)的語(yǔ)法是在C++中習(xí)慣的東西。它們由括號(hào)指定滥嘴,后跟參數(shù)列表木蹬,如[](int a,int b) - > bool {return a> b; }若皱。請(qǐng)注意镊叁,- > bool指定一個(gè)布爾返回值。通常走触,您可以避免表達(dá)返回類型晦譬,因?yàn)樗梢詮暮瘮?shù)體中的返回類型推斷出來。

如果要使用lambda函數(shù)之外的作用域中定義的變量互广,則需要進(jìn)行變量捕獲敛腌。還有可能通過引用或值將參數(shù)傳遞給您的函數(shù)。

  • 要通過引用傳遞惫皱,您需要使用字符啟動(dòng)lambda(就像在函數(shù)中使用引用時(shí)一樣):[&]
  • 要傳遞值像樊,請(qǐng)使用=字符:[=]

還可以通過值和參考來混合和匹配捕獲。

例如旅敷,[=生棍,&foo]將為除foo之外的所有變量創(chuàng)建副本,這些變量通過引用捕獲媳谁。

它有助于理解使用lambdas時(shí)幕后發(fā)生的事情:

事實(shí)證明涂滴,lambdas的實(shí)現(xiàn)方式是創(chuàng)建一個(gè)小類;這個(gè)類重載了operator(),因此它就像一個(gè)函數(shù)一樣晴音。lambda函數(shù)是這個(gè)類的一個(gè)實(shí)例;構(gòu)造類時(shí)柔纵,周圍環(huán)境中的任何變量都將傳遞給lambda函數(shù)類的構(gòu)造函數(shù)并保存為成員變量。事實(shí)上段多,這有點(diǎn)像已經(jīng)可能的仿函數(shù)的想法首量。C++ 11的好處是,這樣做變得非常簡(jiǎn)單——所以你可以一直使用它进苍,而不是僅僅在非常罕見的情況下編寫一個(gè)全新的類是有意義的加缘。

Lambda函數(shù)在EOS智能合約中大量使用,因?yàn)樗鼈兲峁┝艘环N非常方便的方法來修改少量代碼中的數(shù)據(jù)觉啊。標(biāo)準(zhǔn)庫(kù)中有更多函數(shù)拣宏,它們與我們?cè)?code>sort,transform杠人,remove_iffind_if中看到的函數(shù)類似勋乾。它們都通過<algorithm>標(biāo)頭導(dǎo)出宋下。

======================================================================

分享一些比特幣、以太坊辑莫、EOS等區(qū)塊鏈相關(guān)的交互式在線編程實(shí)戰(zhàn)教程:

  • EOS入門教程学歧,本課程幫助你快速入門EOS區(qū)塊鏈去中心化應(yīng)用的開發(fā),內(nèi)容涵蓋EOS工具鏈各吨、賬戶與錢包枝笨、發(fā)行代幣、智能合約開發(fā)與部署揭蜒、使用代碼與智能合約交互等核心知識(shí)點(diǎn)横浑,最后綜合運(yùn)用各知識(shí)點(diǎn)完成一個(gè)便簽DApp的開發(fā)。
  • 深入淺出玩轉(zhuǎn)EOS錢包開發(fā)屉更,本課程以手機(jī)EOS錢包的完整開發(fā)過程為主線徙融,深入學(xué)習(xí)EOS區(qū)塊鏈應(yīng)用開發(fā),課程內(nèi)容即涵蓋賬戶瑰谜、計(jì)算資源欺冀、智能合約、動(dòng)作與交易等EOS區(qū)塊鏈的核心概念萨脑,同時(shí)也講解如何使用eosjs和eosjs-ecc開發(fā)包訪問EOS區(qū)塊鏈脚猾,以及如何在React前端應(yīng)用中集成對(duì)EOS區(qū)塊鏈的支持。課程內(nèi)容深入淺出砚哗,非常適合前端工程師深入學(xué)習(xí)EOS區(qū)塊鏈應(yīng)用開發(fā)。
  • java比特幣開發(fā)教程砰奕,本課程面向初學(xué)者蛛芥,內(nèi)容即涵蓋比特幣的核心概念,例如區(qū)塊鏈存儲(chǔ)军援、去中心化共識(shí)機(jī)制仅淑、密鑰與腳本、交易與UTXO等胸哥,同時(shí)也詳細(xì)講解如何在Java代碼中集成比特幣支持功能涯竟,例如創(chuàng)建地址、管理錢包空厌、構(gòu)造裸交易等庐船,是Java工程師不可多得的比特幣開發(fā)學(xué)習(xí)課程。
  • php比特幣開發(fā)教程嘲更,本課程面向初學(xué)者筐钟,內(nèi)容即涵蓋比特幣的核心概念,例如區(qū)塊鏈存儲(chǔ)赋朦、去中心化共識(shí)機(jī)制篓冲、密鑰與腳本李破、交易與UTXO等,同時(shí)也詳細(xì)講解如何在Php代碼中集成比特幣支持功能壹将,例如創(chuàng)建地址嗤攻、管理錢包、構(gòu)造裸交易等诽俯,是Php工程師不可多得的比特幣開發(fā)學(xué)習(xí)課程妇菱。
  • c#比特幣開發(fā)教程,本課程面向初學(xué)者惊畏,內(nèi)容即涵蓋比特幣的核心概念恶耽,例如區(qū)塊鏈存儲(chǔ)、去中心化共識(shí)機(jī)制颜启、密鑰與腳本偷俭、交易與UTXO等,同時(shí)也詳細(xì)講解如何在C#代碼中集成比特幣支持功能缰盏,例如創(chuàng)建地址涌萤、管理錢包、構(gòu)造裸交易等口猜,是C#工程師不可多得的比特幣開發(fā)學(xué)習(xí)課程负溪。
  • java以太坊開發(fā)教程,主要是針對(duì)java和android程序員進(jìn)行區(qū)塊鏈以太坊開發(fā)的web3j詳解济炎。
  • python以太坊川抡,主要是針對(duì)python工程師使用web3.py進(jìn)行區(qū)塊鏈以太坊開發(fā)的詳解。
  • php以太坊须尚,主要是介紹使用php進(jìn)行智能合約開發(fā)交互崖堤,進(jìn)行賬號(hào)創(chuàng)建、交易耐床、轉(zhuǎn)賬密幔、代幣開發(fā)以及過濾器和交易等內(nèi)容。
  • 以太坊入門教程撩轰,主要介紹智能合約與dapp應(yīng)用開發(fā)胯甩,適合入門。
  • 以太坊開發(fā)進(jìn)階教程堪嫂,主要是介紹使用node.js偎箫、mongodb、區(qū)塊鏈溉苛、ipfs實(shí)現(xiàn)去中心化電商DApp實(shí)戰(zhàn)镜廉,適合進(jìn)階。
  • ERC721以太坊通證實(shí)戰(zhàn)愚战,課程以一個(gè)數(shù)字藝術(shù)品創(chuàng)作與分享DApp的實(shí)戰(zhàn)開發(fā)為主線娇唯,深入講解以太坊非同質(zhì)化通證的概念齐遵、標(biāo)準(zhǔn)與開發(fā)方案。內(nèi)容包含ERC-721標(biāo)準(zhǔn)的自主實(shí)現(xiàn)塔插,講解OpenZeppelin合約代碼庫(kù)二次開發(fā)梗摇,實(shí)戰(zhàn)項(xiàng)目采用Truffle,IPFS想许,實(shí)現(xiàn)了通證以及去中心化的通證交易所伶授。
  • C#以太坊,主要講解如何使用C#開發(fā)基于.Net的以太坊應(yīng)用流纹,包括賬戶管理糜烹、狀態(tài)與交易、智能合約開發(fā)與交互漱凝、過濾器和交易等疮蹦。
  • Hyperledger Fabric 區(qū)塊鏈開發(fā)詳解,本課程面向初學(xué)者茸炒,內(nèi)容即包含Hyperledger Fabric的身份證書與MSP服務(wù)愕乎、權(quán)限策略、通道配置與啟動(dòng)壁公、鏈碼通信接口等核心概念感论,也包含F(xiàn)abric網(wǎng)絡(luò)設(shè)計(jì)、nodejs鏈碼與應(yīng)用開發(fā)的操作實(shí)踐紊册,是Nodejs工程師學(xué)習(xí)Fabric區(qū)塊鏈開發(fā)的最佳選擇比肄。
  • Hyperledger Fabric java 區(qū)塊鏈開發(fā)詳解,課程面向初學(xué)者囊陡,內(nèi)容即包含Hyperledger Fabric的身份證書與MSP服務(wù)薪前、權(quán)限策略、頻道配置與啟動(dòng)关斜、鏈碼通信接口等核心概念,也包含F(xiàn)abric網(wǎng)絡(luò)設(shè)計(jì)铺浇、java鏈碼與應(yīng)用開發(fā)的操作實(shí)踐痢畜,是java工程師學(xué)習(xí)Fabric區(qū)塊鏈開發(fā)的最佳選擇。
  • tendermint區(qū)塊鏈開發(fā)詳解鳍侣,本課程適合希望使用tendermint進(jìn)行區(qū)塊鏈開發(fā)的工程師丁稀,課程內(nèi)容即包括tendermint應(yīng)用開發(fā)模型中的核心概念,例如ABCI接口倚聚、默克爾樹线衫、多版本狀態(tài)庫(kù)等,也包括代幣發(fā)行等豐富的實(shí)操代碼惑折,是go語(yǔ)言工程師快速入門區(qū)塊鏈開發(fā)的最佳選擇授账。

匯智網(wǎng)原創(chuàng)翻譯枯跑,轉(zhuǎn)載請(qǐng)標(biāo)明出處。這里是C++開發(fā)EOS基礎(chǔ)指南:迭代器和Lambda表達(dá)式

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末白热,一起剝皮案震驚了整個(gè)濱河市敛助,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌屋确,老刑警劉巖纳击,帶你破解...
    沈念sama閱讀 212,718評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異攻臀,居然都是意外死亡焕数,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門刨啸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來堡赔,“玉大人,你說我怎么就攤上這事呜投〖有伲” “怎么了?”我有些...
    開封第一講書人閱讀 158,207評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵仑荐,是天一觀的道長(zhǎng)雕拼。 經(jīng)常有香客問我,道長(zhǎng)粘招,這世上最難降的妖魔是什么啥寇? 我笑而不...
    開封第一講書人閱讀 56,755評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮洒扎,結(jié)果婚禮上辑甜,老公的妹妹穿的比我還像新娘。我一直安慰自己袍冷,他們只是感情好磷醋,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,862評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著胡诗,像睡著了一般邓线。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上煌恢,一...
    開封第一講書人閱讀 50,050評(píng)論 1 291
  • 那天骇陈,我揣著相機(jī)與錄音,去河邊找鬼瑰抵。 笑死你雌,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的二汛。 我是一名探鬼主播婿崭,決...
    沈念sama閱讀 39,136評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼拨拓,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了逛球?” 一聲冷哼從身側(cè)響起千元,我...
    開封第一講書人閱讀 37,882評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎颤绕,沒想到半個(gè)月后幸海,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,330評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡奥务,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,651評(píng)論 2 327
  • 正文 我和宋清朗相戀三年物独,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片氯葬。...
    茶點(diǎn)故事閱讀 38,789評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡挡篓,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出帚称,到底是詐尸還是另有隱情官研,我是刑警寧澤,帶...
    沈念sama閱讀 34,477評(píng)論 4 333
  • 正文 年R本政府宣布闯睹,位于F島的核電站戏羽,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏楼吃。R本人自食惡果不足惜始花,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,135評(píng)論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望孩锡。 院中可真熱鬧酷宵,春花似錦、人聲如沸躬窜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)荣挨。三九已至溜族,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間垦沉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評(píng)論 1 267
  • 我被黑心中介騙來泰國(guó)打工仍劈, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留厕倍,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,598評(píng)論 2 362
  • 正文 我出身青樓贩疙,卻偏偏與公主長(zhǎng)得像讹弯,于是被迫代替她去往敵國(guó)和親况既。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,697評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容