2012-09-26 77 views
5

我有這段簡短的代碼片段。我不明白這是什麼意思。我知道這段代碼從輸入中讀取數字,並在unordered_map中計算其頻率。但是什麼是[&](int x)是什麼意思? input(cin)代表什麼?我的意思是括號中的「cin」?那麼for_each如何從input(cin)迭代到空的eof參數?我不明白這整個建築。這個C++/C++ 11的構造是什麼意思?

unordered_map<int,int> frequency; 
istream_iterator<int> input(cin); 
istream_iterator<int> eof; 

for_each(input, eof, [&] (int x) 
    { frequency[x]++; }); 
+6

檢查出新的C++ lamda操作符!這真棒 – Minion91

回答

6

istream_iterator允許你反覆提取的istream項目,您在傳遞給構造函數。 eof對象的解釋如下:

此迭代器的特殊值存在:流結束;當一個 迭代器被設置爲這個值已經到達流的末尾 (運算符void *應用於流返回false)或者已經使用其默認構造函數構造的 (不與任何basic_istream對象與 關聯)。

for_each是一個循環結構,它獲取迭代器#1並遞增它,直到它與迭代器#2相等。這裏需要迭代器將標準輸入cin包裝起來,並將其遞增(這意味着提取項目),直到沒有更多輸入消耗爲止 - 這使得input的比較等於eof並且循環結束。

構造[&] (int x) { frequency[x]++; }anonymous function;它只是簡單的內聯函數寫法。大致相同的效果可以用

unordered_map<int,int> frequency; // this NEEDS to be global now 
istream_iterator<int> input(cin); 
istream_iterator<int> eof; 

void consume(int x) { 
    frequency[x]++; 
} 

for_each(input, eof, consume); 

所以一言以蔽之來實現:該代碼從標準輸入讀取整數,直到所有可用的數據被消耗,保持每個整數的出現頻率的計數的映射。

+0

謝謝,這就是我需要的。 – balent

+0

+1簡潔明瞭! – Walter

1

這是STL 的std ::的for_each(非C++ 11)迭代輸入直到是等於EOF;爲每個值調用lambda [&] (int x) { frequency[x]++; }

因此,此代碼計算istream中字符的頻率;它們保存到地圖

2

您的問題有兩個部分。

  1. 第一個涉及流迭代器。 std::istream_iterator<T>由一些std::istream & s構成,並且在取消引用後,其行爲如同{ T x; s >> x; return x; }。一旦提取失敗,迭代器將變成一個默認構造的迭代器,它充當「結束」迭代器。

    流迭代器允許您將流視爲令牌的容器。例如:

    std::vector<int> v(std::istream_iterator<int>(std::cin), 
            std::istream_iterator<int>()); 
    
    std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " ")); 
    
  2. C++ 11引入lambda表達式,它定義匿名函數或仿函數(稱爲封閉)。一個簡單的一個看起來是這樣的:

    auto f = [](int a, int b) -> double { return double(a)/double(b); }; 
    
    auto q = f(1, 2); // q == 0.5 
    

    f可能已被寫成一個普通的,無功能,但免費的功能將不得不出現在命名空間範圍或爲本地類的靜態成員函數。 (這實際上是lambda表達式的類型!)請注意,lambda表達式的類型是不可知的,只能通過新的auto關鍵字捕獲。

    當它們作爲複雜功能對象可以捕獲環境狀態時,Lambda變得更有用。你舉的例子可能已經這樣寫的:

    auto f = [&frequency](int x) -> void { ++frequency[x]; }; 
    

    出現在第一個括號裏的變量是捕獲。這拉姆達是等同於下面的本地類和對象:而不在捕獲列表&

    ​​

變量由值捕獲,即拷貝在閉合對象所做。作爲一個簡短的例子,你可以說[=][&]捕獲一切通過價值或通過引用分別。