看下面的例子:
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);
}
}
这样就解决了问题。
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
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);
}
}
这样就解决了问题。