pred(*first);
,此时构造函数已经返回binder2nd对象,实质上是用重载()调用刚刚构造好的binder2nd对象,并return回Operation functor的调用,即less(*first, value);
。template <class Predicate>
inline unary_negate<Predicate> not1(const Predicate& pred){
return unary_negate<Predicate>(pred);
}
template <class Predicate>
class unary_negate
: public unary_function<typename Predicate::argument_type, bool>{
protected:
Predicate pred;
public:
explicit unary_negate(const Predicate& x) : pred(x) {}
bool operator()(const typename Predicate::argument_type& x) const{
return !pred(x);
}
};
在被上面的count_if()函数调用时,not1函数对象调用operator()返回里面的相反条件。
在C++11后,bind1st,bind2nd等被bind取代。bind可以绑定四种东西(1)函数与仿函数(2)类的成员函数及数据成员,其中_1必须是某个object的地址
第一种:
double my_divide (double x, double y)
{ return x / y; }
//bind的使用示例
auto fn_five = bind(my_divide, 10, 2); //fn_five() return 10/2
auto fn_half = bind(my_divide, _1, 2); //fn_half(x) return x/2
auto fn_invert = bind(my_divide, _2, _1); //fn_invert(x, y) return y/x
auto fn_rounding = bind<int> (my_divide, _1, _2); //fn_rounding(x, y) return (int)x/y
其中_n为占位符,意思是实际调用第n个参数。如第三个例子_2为第二个参数y,_1位第一个参数x,在后面调用fn_invert(x, y)即可以实现参数互换
第二种:
struct MyPair{
double a, b;
double multiply() { return a * b; }
//member function其实有个argument:this
};
//binding类的成员的示例
MyPair ten_two {10, 2};
auto bound_memfn = bind(&MyPair::multiply(), _1);
//bound_memfn(x) return x.multiply()
auto bound_memdata = bind(&MyPair::a, ten_two);
//bound_memdata() return tem_two.a
auto bound_memdata2 = bind(&MyPair::b, _1);
//bound_memdata2(x) return x.b
可以看出bind可以实现绑定类的成员,无论是数据成员还是函数成员,bind需要传入成员指针,它的_1始终表示对象的this指针,当不指定具体传入的对象时,调用bind后的结果时就需要传入一个object,有点像一个隐藏参数。
以看出逆向迭代器需要满足两个行为:(1)正确地引用元素值。(2)方向和原来相反。以rbegin()为例,它的值按理来说和end()是完全相同的,但是指向的元素一个在前一个在后。以下是逆向迭代器的源码,从运算符重载函数可以看出以上两个行为的体现:
我们知道标准库的copy()函数格式为:copy( begin(), end(), result() )
,将会在目的端进行元素的拷贝赋值,那么如果我们想在目的端做插入赋值该怎么办?答案是使用inserter(),所以copy()函数就可以写成这样:copy( begin(), end(), inserter(container, result()) )
可以看到inserter中也采用了用inserter主函数推导了模板实参Container和Container::iter
的类型后调用次函数insert_iterator。在次函数中实现了操作符=的重载,在调用*result = *first;
时调用operator=()重载,对result迭代器指向的地方做insert()操作,再将insert_iterator同步到insert()返回的指针的后一位,即下一个target上。
注意:insert_iterator的重载的++运算符操作并不做任何事情,只是return *this
,因此++iter;的操作必须在operator=()中实现,以移动target指针
观察构造函数看到,ostream_iterator接收一个basic_ostream和一个分隔符,通过对operator=的重载,将赋值运算符定义为往basic_ostream里面放东西,以此达到输出值的效果。
注意:operator * (),operator++(),operator++(int)什么都不做,只是return *this;
,和传统迭代器不同
可以看到istream_iterator是通过重载operator++()来输入元素的,且在创建一个istream_iterator对象时,就会自动调用operator++(),等待一个数值的输入。若创建一个无参数的istream_iterator,其内部指针in_stream会被置为0,用来标志输入结束。
下面是一个copy函数调用istream_iterator的例子
在第一次创建istream_iterator对象时,已经输入了一个数值在对象的value成员中,调用*返回value成员,进行对inserter()函数返回的对象赋值,后面将inserter()对象++后再讲istream_iterator++,输入第二个数值,在下一轮赋给inserter()对象。