関数オブジェクトステータス(Function Object State)取得--参照転送とfor_each()


一般的にfunction objectのデフォルト値は渡され、その状態は取得できません.本明細書では、伝達およびfor_を参照します.each()の2つの方法でfunction object状態を取得します.
参照方式伝達function object
function objectプログラムの例を参照して渡します.
#include 
#include 
#include 
#include 

using namespace std;

template <typename T>
void print_elems(T coll)
{
    for (auto elem : coll)
    {
        cout << elem << ' ';
    }
    cout << endl;
}

class IntSequence
{
private:
    int value_;
public:
    IntSequence(int initial_value) //    
        : value_(initial_value)
    {}

    int operator() ()               //"    "
    {
        return ++value_;
    }
};

int main()
{
    list<int> coll;
    IntSequence seq(1);

    //  4   ,    ,        
    generate_nlist<int>>, int, IntSequence&>
        (back_inserter(coll),           //    
        4,                              //4   
        seq);                           //    
    print_elems(coll);

    //   42       
    generate_n(back_inserter(coll), 4, IntSequence(42));
    print_elems(coll);

    //       seq,     ,        5  
    generate_n(back_inserter(coll), 4, seq);
    print_elems(coll);

    //         seq,     ,        5  
    generate_n(back_inserter(coll), 4, seq);
    print_elems(coll);

    system("pause");
}

実行結果(Linux環境で結果、VS 2013環境で結果は値伝達、なぜか..):
2 3 4 5
2 3 4 5 43 44 45 46
2 3 4 5 43 44 45 46 6 7 8 9
2 3 4 5 43 44 45 46 6 7 8 9 6 7 8 9

プログラム解析:generatorを最初に呼び出すn()の場合function object seqは参照で伝達され、template実参は表示を理解すればよい.
generate_nlist<int>>, int, IntSequence&>
            (back_inserter(coll),           //    
            4,                              //4   
            seq);                           //    

呼び出し後、seq内部値が変更されました.
3回目の呼び出しseqで生成されたシーケンスは、1回目の呼び出しで生成されたシーケンスに接続されます.値伝達seqであるため:
generate_n(back_inserter(coll), 4, seq);

だから今回の呼び出しはseqの状態を変えることはありません.最後にgenerateを呼び出しますn()時シーケンスはまた5から始まる.
for_each()呼び出し
for_についてeach()の次の例では、シーケンスの平均値を処理します.
#include 
#include 
#include 

using namespace std;

class MeanValue
{
private:
    long num_;
    long sum_;
public:
    MeanValue()
        : num_(0),
        sum_(0){
    }
    //function call
    void operator() (int elem)
    {
        ++num_;
        sum_ += elem;
    }

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

int main()
{
    vector<int> coll = { 1, 2, 3, 4, 5, 6, 7, 8 };

    MeanValue mv = for_each(coll.begin(), coll.end(), MeanValue());

    cout << "mean value :" << mv.value() << endl;

    system("pause");
}
/*
    
mean value :4.5
       . . .
*/

プログラム解析:MeanValue()式は、要素の数を記録し、要素の合計を計算するfunction objectを生成します.このfunction objectをfor_に渡すeach()は、コンテナcoll内の各要素に対してfunction objectを呼び出します.
MeanValue mv = for_each(coll.begin(), coll.end(), MeanValue());

返されるfunction objectはmvに付与、mvを呼び出すことができる.value()はステータスをクエリーします.