class FunctionObjectType {
public:
void operator() () {
statements;
}
}
这种定义形式更为复杂,却有三大有点:
eg 1:以Function Object为排序准则(Sorting Criterion)
Class Person{
public:
sting firstname() const;
string lastname() const;
...
};
class PersonSortCriterion{
public:
bool operator () (const Person& p1, const Person& p2) const {
return p1.lastname() < p2.lastname() ||
(p1.lastname() == p2.lastname() &&
p1.firstname() < p2.firstname());
}
};
int main () {
set coll; //create a set with special sorting criterion
for (auto pos = coll.begin(); pos != coll.end(); ++pos){
...
}
....
}
eg 2: Function Object拥有内部状态(Internal State)
class IntSequence{
private:
int value;
public:
IntSequence (int initialValue) : value(initialValue) {}
int operator () () {return ++value;}
};
int main () {
list coll;
generate_n (back_inserter(coll),
9,
IntSequence(1));
generate(next(coll.begin()),
prev(coll.end()),
IntSequence(42));
}
class Nth {
private:
int nth;
int count;
public:
Nth (int n) : nth(n), count(0) {}
bool operator() (int) {return ++count == nth;}
};
int main() {
list coll = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
PRINT_ELEMENTS(coll, "coll: ");
list::iterator pos;
pos = remove_if(coll.begin(), coll.end(), Nth(3));
coll.erase(pos, coll.end());
PRINT_ELEMENTS(coll, "3rd removed: ");
}
运行结果
coll: 1 2 3 4 5 6 7 8 9 10
3rd removed: 1 2 4 5 7 8 9 10
两个(而非一个)元素被移除了。因为该算法的常见做法会在其内部保留predicate的一个拷贝
template
ForwIter std::remove_if(ForwIter beg, ForeIter 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);
}
}
这个算法使用find_if()查找应被移除的第一个元素。然而,接下来它使用传入的predicate op的拷贝去处理剩余的元素,这时原始状态下的Nth再次被使用,因而会移除剩余元素中的第3个元素,也就是整体的第6个元素。
predicate不应该因为被调用而改变自身状态;predicate的拷贝应该和其正本有着相同的状态。应当将operator()声明为const成员函数。