前言
关于配接器,之前在分析序列式容器时就已经分析过queue
和stack
,它们也是配接器的一种,通过使用其他容器的接口然后自己加以修饰,形成另外一种容器。除了应用在容器上之外,还有关于应用在仿函数上的配接器,就如我们上一小节分析仿函数时里面的例子一样。还有一种是应用在迭代器上的配接器,等下我们会进行分析。
应用于容器的配接器
关于这一部分,之前已经分析过queue
和stack
的实现了,这里就不做赘述了。默认情况下其实就是使用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
中,若感兴趣可以再去看看。