SGISTL源码探究-配接器

来源:互联网 发布:火山软件开发平台 编辑:程序博客网 时间:2024/06/06 11:49

前言

关于配接器,之前在分析序列式容器时就已经分析过queuestack,它们也是配接器的一种,通过使用其他容器的接口然后自己加以修饰,形成另外一种容器。除了应用在容器上之外,还有关于应用在仿函数上的配接器,就如我们上一小节分析仿函数时里面的例子一样。还有一种是应用在迭代器上的配接器,等下我们会进行分析。

应用于容器的配接器

关于这一部分,之前已经分析过queuestack的实现了,这里就不做赘述了。默认情况下其实就是使用deque容器提供的部分接口完成自己的功能。

应用于仿函数的配接器

在上一小节中,我们已经看到了个别应用于仿函数上对配接器,要想仿函数可配接,都需要继承unary_function或者binary_function。这里我们再选取stl_function.h中的一个例子看一看。

bind1st

//该配接器的作用是将二元函数的第一个参数绑定为指定值,将二元函数对象转换为一元函数对象//下面又出现了typename的用法,希望你没有忘记...(向编译器通知未知标识符是类型)template <class Operation>class binder1st  : public unary_function<typename Operation::second_argument_type,                          typename Operation::result_type> {protected:  //二元函数  Operation op;  //value用于保存第一个参数类型的值  typename Operation::first_argument_type value;public:  //构造函数,绑定二元函数,以及第一个参数  binder1st(const Operation& x,            const typename Operation::first_argument_type& y)      : op(x), value(y) {}  typename Operation::result_type  //重载()操作符,传入第二个参数,直接使用该二元函数以及绑定的第一个参数进行运算并返回  operator()(const typename Operation::second_argument_type& x) const {    return op(value, x);  }};template <class Operation, class T>inline binder1st<Operation> bind1st(const Operation& op, const T& x) {  //通过传入的x获取到参数的类型  typedef typename Operation::first_argument_type arg1_type;  //返回绑定好的配接器  return binder1st<Operation>(op, arg1_type(x));}

还有绑定二元函数以及第二个参数的仿函数配接器bind2nd,实现的思路一样,只是绑定的参数不一样。

应用于迭代器的配接器

STL提供了许多应用于迭代器上的配接器,如insert iterators,reverse iterators,iostream iterators等,这里我们主要分析reverse iterators,因为之前在分析容器时,其实大部分都提供了reverse iterators,当时没有进行分析,这个时候可以弥补上了。其余的部分如果感兴趣可以自己看看。

reverse iterator

template <class Iterator>class reverse_iterator{protected:  //以一个迭代器作为成员  Iterator current;public:  //逆向迭代器的5种相应型别,和正向的正向迭代器相同  typedef typename iterator_traits<Iterator>::iterator_category          iterator_category;  typedef typename iterator_traits<Iterator>::value_type          value_type;  typedef typename iterator_traits<Iterator>::difference_type          difference_type;  typedef typename iterator_traits<Iterator>::pointer          pointer;  typedef typename iterator_traits<Iterator>::reference          reference;  //正向迭代器  typedef Iterator iterator_type;  //逆向迭代器  typedef reverse_iterator<Iterator> self;public:  reverse_iterator() {}  //将逆向迭代器与某种迭代器联系起来  explicit reverse_iterator(iterator_type x) : current(x) {}  reverse_iterator(const self& x) : current(x.current) {}  //返回正向迭代器        iterator_type base() const { return current; }  //逆向迭代器取值时,先将正向迭代器后退一位,再取值  reference operator*() const {    Iterator tmp = current;    return *--tmp;  }  //++变成--  self& operator++() {    --current;    return *this;  }  self operator++(int) {    self tmp = *this;    --current;    return tmp;  }  //--变成++  self& operator--() {    ++current;    return *this;  }  self operator--(int) {    self tmp = *this;    ++current;    return tmp;  }  //前进和后退方向相反  self operator+(difference_type n) const {    return self(current - n);  }  self& operator+=(difference_type n) {    current -= n;    return *this;  }  self operator-(difference_type n) const {    return self(current + n);  }  self& operator-=(difference_type n) {    current += n;    return *this;  }  reference operator[](difference_type n) const { return *(*this + n); }    };  /* 以下操作符都是使用正向迭代器重载的进行判断 */     template <class Iterator>  inline bool operator==(const reverse_iterator<Iterator>& x,                         const reverse_iterator<Iterator>& y) {    return x.base() == y.base();  }  template <class Iterator>  inline bool operator<(const reverse_iterator<Iterator>& x,                        const reverse_iterator<Iterator>& y) {    return y.base() < x.base();  }  template <class Iterator>  inline typename reverse_iterator<Iterator>::difference_type  operator-(const reverse_iterator<Iterator>& x,            const reverse_iterator<Iterator>& y) {    return y.base() - x.base();  }  template <class Iterator>  inline reverse_iterator<Iterator>  operator+(reverse_iterator<Iterator>::difference_type n,            const reverse_iterator<Iterator>& x) {    return reverse_iterator<Iterator>(x.base() - n);  }

小结

关于配接器的分析就到此为止,举了几个例子配合理解,其实STL中关于配接器的使用还是比较多,特别是用在仿函数上的配接器,都实现在stl_function.h中,若感兴趣可以再去看看。

原创粉丝点击