STL函数对象2

看下面的例子:
class IntSequence {
private:
int value;
public:
IntSequence (int initialValue): value(initialValue) {}
int operator() () {return value++;}
};
list<int> coll;
generate_n (back_inserter(coll),9, IntSequence (1)); 
PRINT_ELEMENTS(coll);
Output:
1 2 3 4 5 6 7 8 9

有时候我们想保存函数对象的状态,像上面的例子函数对象是按值传递的,如果下次再次用到还是函数对象的初始状态:
有两种方法解决:
1.       传递函数对象的引用而非值
2.       用for_each()函数。

看这样一个例子:函数上面的函数对象IntSequence。
主函数中:
list<int> coll;
IntSequence seq(1);
generate_n<back_insert_iterator<list<int> >,int, IntSequence&>(back_inserter(coll),4.Seq);
PRINT_ELEMENTS(coll);
generate_n (back_inserter(coll), 4, IntSequence (42)) ;
PRINT_ELEMENTS(coll);
generate_n (back_inserter(coll), 4, seq) ;
PRINT_ELEMENTS(coll);
Output:
1 2 3 4
1 2 3 4 42 43 44 45
1 2 3 4 42 43 44 45 5 6 7 8
这样就可以保存函数对象的状态。

对于 For_each 函数它可以把函数对象返回出来。
class MeanValue {
private:
long num; //number of elements
long sum; //sum of all element values
public:
MeanValue() : num(0), sum(0) {}
void operator() (int elem) {num++;sum += elem; }
double value() {return static_cast<double>(sum) / static_cast<double>(num);}
}

vector<int> coll;
for (int i=1; i<=8; ++i) {coll.push_back(i);}
MeanValue mv = for_each (coll.begin(), coll.end(), MeanValue()); 
cout << "mean value: " << mv.value() << endl;
output:
mean value: 4.5



看下面一个有趣的例子:
class Nth { //function object that returns true for the nth call
private:
int nth; //call for which to return true
int count; //call counter
public:
Nth (int n) : nth (n), count (0) {}
bool operator() (int) {return ++count == nth;}
};
主程序:
list<int> coll;
for (int i=1; i<=9; ++i) {coll.push_back(i);}
PRINT_ELEMENTS(coll,"coll: ");

list<int>::iterator pos;
pos = remove_if (coll.begin(),coll.end(), Nth(3)), /
coll.erase (pos,coll.end());
PRINT_ELEMENTS (coll, "nth removed: ");
}
Output
coll: 1 2 3 4 5 6 7 8 9
nth removed: 1 2 4 5 7 8 9
为什么会产生这样的结果呢?这是因为在函数的执行中函数赋值了内部的断言,看下 remove_if() 定义:
template <class ForwIter, class Predicate>
ForwIter std::remove_if(ForwIter beg, ForwIter end,Predicate op){
beg = find_if(beg, end, op);
if (beg == end) {return beg;}
else {ForwIter next = beg;return remove_copy_if(++next, end, beg, op);}
}
这样就很清楚了, op 按值传递给 find_if, 在再传递给 remove_copy_if 时还是原来的 op, 而是不是经过运行的 OP 。当然也有解决的方法。你可以重新 remove_if() 函数,像这样:
template <class ForwIter, class Predicate>
ForwIter std::remove_if(ForwIter beg, ForwIter end,Predicate op)
{
while (beg != end && !op(*beg)) {++beg;}
if (beg == end) {return beg;}
else {
ForwIter next = beg;
return remove_copy_if(++next, end, beg, op);
}
}
这样就解决了问题。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值