C++0x嘗鮮:用lambda運算式類比Ruby的過程對象

來源:互聯網
上載者:User
文章目錄
  • 關於C++0x
  • 關於lambda運算式
  • Ruby代碼
  • C++代碼
關於C++0x預計於明年底推出的新標準C++0x,雖說已接近收官階段,卻仍有若干有待接納的新提案被提出。尤其值得關注的是,與lambda運算式以及局部函數相關的提案“Unified Function Syntax(統一的函數文法)”,儘管不受標準委員會待見(兩年間曆經四次延遲表決,兩次不予通過),仍然“頑強地”推出了其第7個版本N2989,提案作者鍥而不捨的精神實在令人欽佩。 關於lambda運算式受函數型編程風格的影響,一些OOP為主題思想的靜態語言紛紛推出了lambda這一以短小的匿名函數為特點的語言設施,典型的如微軟的VB9和C#3.0。與此相對應的是,眾多動態指令碼語言(python, ruby, javascript)則早就具備了相應的語言特性,Ruby的過程對象便是其中一例。這一次借C++0x新標準的東風,C++語言不甘人後同樣引入了這一激動人心的新特性,為函數型編程風格在C++語言內的進一步推廣打下了堅實的基礎。 以下用C++0x中的lambda運算式來類比Ruby的過程對象。 Ruby代碼class Array<br /> def inject(n)<br /> each { |value| n = yield(n, value) }<br /> n<br /> end<br /> def sum<br /> inject(0) { |n, value| n + value }<br /> end<br /> def product<br /> inject(1) { |n, value| n * value }<br /> end<br /> def find<br /> for i in 0...size<br /> value = self[i]<br /> return value if yield(value)<br /> end<br /> return nil<br /> end<br />end<br />[ 1, 2, 3, 4, 5 ].sum # 15<br />[ 1, 2, 3, 4, 5 ].product # 120<br />[ 1, 2, 3, 4, 5 ].find {|v| v*v > 10 } # 4<br />有關Ruby的過程對象以及這段Ruby代碼的說明,請參考Ruby語言中的泛回調及其在C++語言中的類比實現一文。 C++代碼#include <array><br />#include <functional><br />//#include <numeric><br />#include <algorithm><br />#include <boost/assign.hpp><br />#include <iostream></p><p>using namespace std;</p><p>template<typename T><br />struct Array : public vector<T><br />{<br />template<typename _Iter><br />Array(_Iter _First, _Iter _Last) : vector(_First, _Last) {}</p><p>T inject(T n, function<T(T,T)> f) const {<br />for_each(begin(), end(), [&](T value){n = f(n, value);});<br />return n;<br />//return accumulate(begin(), end(), n, f);<br />}<br />T sum() const {<br />return inject(0, [](T n, T value){return n + value;});<br />}<br />T product() const {<br />return inject(1, [](T n, T value){return n * value;});<br />}<br />const T* find(function<bool(T)> f) const {<br />auto i = find_if(begin(), end(), f);<br />return i == end() ? nullptr : &*i;<br />}<br />};</p><p>int main()<br />{<br />Array<int> a = boost::assign::list_of(1)(2)(3)(4)(5);<br />//Array<int> a = {1, 2, 3, 4, 5};<br />cout << a.sum() << endl;<br />cout << a.product() << endl;<br />cout << *a.find([](int v){return v * v > 10;}) << endl;</p><p>return 0;<br />}</p><p>//15<br />//120<br />//4C++代碼說明
  1. Ruby數組用標準庫的vector組件來類比。
  2. Ruby數組的初始化用boost庫的assign組件來類比。
    註:Array類中若加入初始化列表構造器(C++0x新特性,VC10尚不支援),其初始化方式將可得到明顯改善(第36行)。
  3. Ruby過程對象用lambda運算式來類比。
  4. Ruby代碼中的each方法用標準庫的for_each演算法來類比。
  5. 如果不類比具體演算法,Ruby代碼中的inject方法也可用標準庫的accumulate演算法來實現。
    具體做法為:注釋掉第17,18行,反注釋第3,19行。
  6. Ruby代碼中的find方法直接用標準庫的find_if演算法來實現(具體演算法不予類比)。
  7. 第28行的auto是C++0x新引入的關鍵字,用於自動類型推導,與C#3.0中的var相類似。
    註:嚴格地說,是“舊瓶裝新酒”,auto關鍵字的原意(表示自動分配的局部變數類型,由於可省略而絕少被使用)在新標準中已經被廢除。
  8. 第29行的nullptr也是C++0x新引入的關鍵字,用於替代NULL表示null 指標。
  9. 原屬於Boost庫的模版類function在新標準中將正式進入標準庫。
    function類型的變數不僅能存放函數指標和函數對象,也能存放lambda運算式。
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.