一般情况下function object默认值传递,无法获取其状态。本文以引用传递和for_each()两种方法获取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()的如下示例,处理一个序列的平均值:
#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()查询其状态。