函数对象状态(Function Object State)获取 -- 引用传递和for_each()

一般情况下function object默认值传递,无法获取其状态。本文以引用传递和for_each()两种方法获取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环境下结果,VS2013环境下结果是值传递,不知为何。。):

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内部值被改变了。

第三次调用seq产生的序列会接续第一次调用产生的序列。由于是值传递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()查询其状态。

你可能感兴趣的:(《C++标准库》)