天天看點

for_each()算法的使用

for_each()算法非常靈活,允許不同方式通路、處理、修改每一個元素。

UnaryProc

1、 對區間[beg, end)中每一個元素調用:

2、 傳回op的一個拷貝(副本),自C++11起,傳回的op已被改動過

3、 op可以改動元素。

4、 op的任何傳回值都會被忽略。

5、 複雜度:線性。調用op()共numElems次。

不修改元素程式執行個體

把每一個元素傳給一個lambda,後者将它所獲得的元素列印出來:

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

template <typename T>
inline void insert_elems(T& coll, int first, int last)
{
    for (int i = first; i <= last; i++)
    {
        coll.insert(coll.end(), i);
    }
}

int main()
{
    vector<int> coll;
    insert_elems(coll, , );

    for_each(coll.begin(), coll.end(), 
        [](int elem)
        {
            cout << elem << ' ';
        });

    cout << endl;
    system("pause");
}
           

運作結果:

/*
1 2 3 4 5 6 7 8 9
請按任意鍵繼續. . .
*/
           

下例示範如何改變元素

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

template <typename T>
inline void insert_elems(T& coll, int first, int last)
{
    for (int i = first; i <= last; i++)
    {
        coll.insert(coll.end(), i);
    }
}

template <typename T>
inline void print(T coll)
{
    for (auto elem : coll)
    {
        cout << elem << ' ';
    }
    cout << endl;
}
int main()
{
    vector<int> coll;
    insert_elems(coll, , );

    //每個元素+10
    for_each(coll.begin(), coll.end(),
        [](int& elem)
    {
        elem += ;
    });
    print(coll);

    //把第一個元素的值加至每一個元素
    for_each(coll.begin(), coll.end(),
        [=](int& elem)  //=operator
    {
        elem += *coll.begin();
    });
    print(coll);

    system("pause");
}
           
/*
11 12 13 14 15 16 17 18 19
22 23 24 25 26 27 28 29 30
請按任意鍵繼續. . .
*/
           

程式分析:

改動元素必須聲明elem的類型為引用(reference),也必須定義lambda的capture像這樣[=],為的是加“第一進制素的拷貝”。

如果第二個for_each()傳入引用,即把[=]換成[&],

for_each(coll.begin(), coll.end(),
    [&](int& elem)  //=operator
    {
        elem += *coll.begin();
    });
           

“加數”會改變,導緻以下輸出:

11 12 13 14 15 16 17 18 19
22 34 35 36 37 38 39 40 41
請按任意鍵繼續. . .
           

利用for_each()的傳回值

第三個例子展示如何利用for_each()的傳回值。

for_each()有一個特殊性質就是它能傳回其操作,我們可以利用這一特性,處理和傳回“置于該操作中的結果”:

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

template <typename T>
inline void insert_elems(T& coll, int first, int last)
{
    for (int i = first; i <= last; i++){
        coll.insert(coll.end(), i);
    }
}

class MeanValue
{
private:
    long num_;
    long sum_;
public:
    MeanValue()
        : num_()
        , sum_()
    {}

    void operator()(int elem){
        ++num_;
        sum_ += elem;
    }

    operator double(){
        return static_cast<double>(sum_) / static_cast<double>(num_);
    }
};

int main()
{
    vector<int> coll;
    insert_elems(coll, , );

    double mv = for_each(coll.begin(), coll.end(),MeanValue());
    cout << "mean value: " << mv << endl;

    system("pause");
}
           
/*
mean value: 4.5
請按任意鍵繼續. . .
*/