点击查看Evernote原文。
#@author: gr
#@date: 2014-09-27
#@email: forgerui@gmail.com
Chapter6 函数子、函数子类、函数及其他
Topic 38: 遵循按值传递的原则来设计函数子类
函数作为参数传递的是函数指针,所以尽量使函数子是单态的,可以使用这个函数去调用其它多态函数实现多态。这样也可以保证函数子的小巧。
Topic 39: 确保判别式是“纯函数”
一个判别式是一个返回为bool
类型的函数,包括判别子类和判别函数。纯函数所能访问的数据应该仅局限于参数的函数,不可修改状态。否则,在多次调用判别式时,可能改变状态而得到不同的结果。比如:在一个循环中多次调用一个判别式,可能得到不同的结果。
所以将函数声明为const
形式:
class BadPredicate: public unary_function<Widget, bool>{
pulbic:
bool operator()(const Widget&)const{
//不允许修改状态
//...
return ...;
}
}
Topic 40: 若一个类是函数子,则应使它可配接
如果一个函数子类的operator()
只有一个实参,那么它应该从std::unary_function
继承;如果函数子类的operator()
有两个实参,那么它应该从std::binary_function
继承。返回类型是operator()
的最后一个实参。
not1
和bind2nd
只能用于可配接的函数对象,如果函数子类不是从unary_function
或binary_function
继承而来,则无法配接。
template<typename T>
class MeetsThreashold: public std::unary_function<Widget, bool>{
private:
const T threshold;
public:
MeetsThreshold(const T& threshold);
bool operator() (const Widget&) const;
}
Topic 41: 理解ptr_fun
、mem_fun
和mem_fun_ref
的来由
1. 使用STL算法可以调用函数,但无法使用类成员函数。mem_fun
和mem_fun_ref
被用来高速成员函数,使之可以像函数一样被接受。
for_each(vw.begin(), vw.end(), mem_fun(&Widget::test));
2. ptr_fun
将函数传给STL组件时使用,可以不用,等编译器提醒时再加上。
for_each(vw.begin(), vw.end(), ptr_fun(test));
Topic 42: 确保less<T>
与operator<
具有相同的语义
less<T>
默认调用operator<
,如果修改less<T>
,会使operator>
和less<T>
意义不一致。
当你需要另外一个less<T>
版本实现时,尽量不要修改原less<T>
,而是用其它名称进行命名,确保operator<
与less<T>
有相同的意义。
struct selfLess: public binary_function<Widget, Widget, bool>{
bool operator()(const Widget& lhs, const Widget& rhs) const{
return lhs.maxSpeed() < rhs.maxSpeed();
}
};